objects-printer.cc 40.3 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/objects.h"
6

7
#include "src/disasm.h"
8
#include "src/disassembler.h"
9
#include "src/interpreter/bytecodes.h"
10
#include "src/objects-inl.h"
11
#include "src/ostreams.h"
12
#include "src/regexp/jsregexp.h"
13 14 15 16 17 18

namespace v8 {
namespace internal {

#ifdef OBJECT_PRINT

19
void Object::Print() {
20 21
  OFStream os(stdout);
  this->Print(os);
22
  os << std::flush;
23 24 25
}


26
void Object::Print(std::ostream& os) {  // NOLINT
27
  if (IsSmi()) {
28
    Smi::cast(this)->SmiPrint(os);
29
  } else {
30
    HeapObject::cast(this)->HeapObjectPrint(os);
31 32 33 34
  }
}


35
void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
36
  os << reinterpret_cast<void*>(this) << ": [" << id << "]";
37 38 39
}


40
void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
41 42
  InstanceType instance_type = map()->instance_type();

43
  HandleScope scope(GetIsolate());
44
  if (instance_type < FIRST_NONSTRING_TYPE) {
45
    String::cast(this)->StringPrint(os);
46 47 48 49
    return;
  }

  switch (instance_type) {
50
    case SYMBOL_TYPE:
51
      Symbol::cast(this)->SymbolPrint(os);
52
      break;
53
    case MAP_TYPE:
54
      Map::cast(this)->MapPrint(os);
55 56
      break;
    case HEAP_NUMBER_TYPE:
57
      HeapNumber::cast(this)->HeapNumberPrint(os);
58
      break;
59
    case MUTABLE_HEAP_NUMBER_TYPE:
60 61 62
      os << "<mutable ";
      HeapNumber::cast(this)->HeapNumberPrint(os);
      os << ">";
63
      break;
64 65
    case SIMD128_VALUE_TYPE:
      Simd128Value::cast(this)->Simd128ValuePrint(os);
66
      break;
67
    case FIXED_DOUBLE_ARRAY_TYPE:
68
      FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
69
      break;
70
    case FIXED_ARRAY_TYPE:
71
      FixedArray::cast(this)->FixedArrayPrint(os);
72 73
      break;
    case BYTE_ARRAY_TYPE:
74
      ByteArray::cast(this)->ByteArrayPrint(os);
75
      break;
76 77 78
    case BYTECODE_ARRAY_TYPE:
      BytecodeArray::cast(this)->BytecodeArrayPrint(os);
      break;
79 80 81
    case TRANSITION_ARRAY_TYPE:
      TransitionArray::cast(this)->TransitionArrayPrint(os);
      break;
82
    case FREE_SPACE_TYPE:
83
      FreeSpace::cast(this)->FreeSpacePrint(os);
84
      break;
85

86 87 88 89
#define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
  case Fixed##Type##Array::kInstanceType:                      \
    Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os);  \
    break;
90

91 92
    TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
#undef PRINT_FIXED_TYPED_ARRAY
93

94
    case FILLER_TYPE:
95
      os << "filler";
96 97 98 99
      break;
    case JS_OBJECT_TYPE:  // fall through
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    case JS_ARRAY_TYPE:
100
    case JS_GENERATOR_OBJECT_TYPE:
101
    case JS_PROMISE_TYPE:
102
      JSObject::cast(this)->JSObjectPrint(os);
103
      break;
104 105 106
    case JS_REGEXP_TYPE:
      JSRegExp::cast(this)->JSRegExpPrint(os);
      break;
107
    case ODDBALL_TYPE:
108
      Oddball::cast(this)->to_string()->Print(os);
109
      break;
110
    case JS_MODULE_TYPE:
111
      JSModule::cast(this)->JSModulePrint(os);
112
      break;
113 114 115
    case JS_BOUND_FUNCTION_TYPE:
      JSBoundFunction::cast(this)->JSBoundFunctionPrint(os);
      break;
116
    case JS_FUNCTION_TYPE:
117
      JSFunction::cast(this)->JSFunctionPrint(os);
118 119
      break;
    case JS_GLOBAL_PROXY_TYPE:
120
      JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
121 122
      break;
    case JS_GLOBAL_OBJECT_TYPE:
123
      JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
124 125
      break;
    case JS_VALUE_TYPE:
126
      JSValue::cast(this)->JSValuePrint(os);
127
      break;
128
    case JS_DATE_TYPE:
129
      JSDate::cast(this)->JSDatePrint(os);
130
      break;
131
    case CODE_TYPE:
132
      Code::cast(this)->CodePrint(os);
133
      break;
134
    case JS_PROXY_TYPE:
135
      JSProxy::cast(this)->JSProxyPrint(os);
136
      break;
137
    case JS_SET_TYPE:
138
      JSSet::cast(this)->JSSetPrint(os);
139 140
      break;
    case JS_MAP_TYPE:
141
      JSMap::cast(this)->JSMapPrint(os);
142
      break;
143
    case JS_SET_ITERATOR_TYPE:
144
      JSSetIterator::cast(this)->JSSetIteratorPrint(os);
145 146
      break;
    case JS_MAP_ITERATOR_TYPE:
147
      JSMapIterator::cast(this)->JSMapIteratorPrint(os);
148
      break;
149
    case JS_WEAK_MAP_TYPE:
150
      JSWeakMap::cast(this)->JSWeakMapPrint(os);
151
      break;
152
    case JS_WEAK_SET_TYPE:
153
      JSWeakSet::cast(this)->JSWeakSetPrint(os);
154
      break;
155
    case FOREIGN_TYPE:
156
      Foreign::cast(this)->ForeignPrint(os);
157 158
      break;
    case SHARED_FUNCTION_INFO_TYPE:
159
      SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
160
      break;
161
    case JS_MESSAGE_OBJECT_TYPE:
162
      JSMessageObject::cast(this)->JSMessageObjectPrint(os);
163
      break;
164
    case CELL_TYPE:
165
      Cell::cast(this)->CellPrint(os);
166 167
      break;
    case PROPERTY_CELL_TYPE:
168
      PropertyCell::cast(this)->PropertyCellPrint(os);
169
      break;
ulan@chromium.org's avatar
ulan@chromium.org committed
170 171 172
    case WEAK_CELL_TYPE:
      WeakCell::cast(this)->WeakCellPrint(os);
      break;
173
    case JS_ARRAY_BUFFER_TYPE:
174
      JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
175
      break;
176
    case JS_TYPED_ARRAY_TYPE:
177
      JSTypedArray::cast(this)->JSTypedArrayPrint(os);
178
      break;
179
    case JS_DATA_VIEW_TYPE:
180
      JSDataView::cast(this)->JSDataViewPrint(os);
181
      break;
182 183
#define MAKE_STRUCT_CASE(NAME, Name, name) \
  case NAME##_TYPE:                        \
184
    Name::cast(this)->Name##Print(os);     \
185 186 187 188 189
    break;
  STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE

    default:
190
      os << "UNKNOWN TYPE " << map()->instance_type();
191 192 193 194 195 196
      UNREACHABLE();
      break;
  }
}


197 198 199 200 201 202 203 204 205
void Simd128Value::Simd128ValuePrint(std::ostream& os) {  // NOLINT
#define PRINT_SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \
  if (Is##Type()) return Type::cast(this)->Type##Print(os);
  SIMD128_TYPES(PRINT_SIMD128_VALUE)
#undef PRINT_SIMD128_VALUE
  UNREACHABLE();
}


206 207 208 209 210 211 212 213 214 215
void Float32x4::Float32x4Print(std::ostream& os) {  // NOLINT
  char arr[100];
  Vector<char> buffer(arr, arraysize(arr));
  os << std::string(DoubleToCString(get_lane(0), buffer)) << ", "
     << std::string(DoubleToCString(get_lane(1), buffer)) << ", "
     << std::string(DoubleToCString(get_lane(2), buffer)) << ", "
     << std::string(DoubleToCString(get_lane(3), buffer));
}


216 217 218 219 220 221 222 223
#define SIMD128_INT_PRINT_FUNCTION(type, lane_count)                \
  void type::type##Print(std::ostream& os) {                        \
    char arr[100];                                                  \
    Vector<char> buffer(arr, arraysize(arr));                       \
    os << std::string(IntToCString(get_lane(0), buffer));           \
    for (int i = 1; i < lane_count; i++) {                          \
      os << ", " << std::string(IntToCString(get_lane(i), buffer)); \
    }                                                               \
224
  }
225
SIMD128_INT_PRINT_FUNCTION(Int32x4, 4)
226
SIMD128_INT_PRINT_FUNCTION(Uint32x4, 4)
227
SIMD128_INT_PRINT_FUNCTION(Int16x8, 8)
228
SIMD128_INT_PRINT_FUNCTION(Uint16x8, 8)
229
SIMD128_INT_PRINT_FUNCTION(Int8x16, 16)
230
SIMD128_INT_PRINT_FUNCTION(Uint8x16, 16)
231 232 233 234 235 236 237 238 239 240 241
#undef SIMD128_INT_PRINT_FUNCTION


#define SIMD128_BOOL_PRINT_FUNCTION(type, lane_count)            \
  void type::type##Print(std::ostream& os) {                     \
    char arr[100];                                               \
    Vector<char> buffer(arr, arraysize(arr));                    \
    os << std::string(get_lane(0) ? "true" : "false");           \
    for (int i = 1; i < lane_count; i++) {                       \
      os << ", " << std::string(get_lane(i) ? "true" : "false"); \
    }                                                            \
242
  }
243 244 245 246
SIMD128_BOOL_PRINT_FUNCTION(Bool32x4, 4)
SIMD128_BOOL_PRINT_FUNCTION(Bool16x8, 8)
SIMD128_BOOL_PRINT_FUNCTION(Bool8x16, 16)
#undef SIMD128_BOOL_PRINT_FUNCTION
247 248


249
void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
250
  os << "byte array, data starts at " << GetDataStartAddress();
251 252 253
}


254 255 256 257 258
void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
  Disassemble(os);
}


259
void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
260
  os << "free space, size " << Size();
261 262 263
}


264
template <class Traits>
265 266
void FixedTypedArray<Traits>::FixedTypedArrayPrint(
    std::ostream& os) {  // NOLINT
267
  os << "fixed " << Traits::Designator();
268 269
}

270

271
void JSObject::PrintProperties(std::ostream& os) {  // NOLINT
272 273
  if (HasFastProperties()) {
    DescriptorArray* descs = map()->instance_descriptors();
274
    for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
275
      os << "\n   ";
276 277
      descs->GetKey(i)->NamePrint(os);
      os << ": ";
278
      switch (descs->GetType(i)) {
279
        case DATA: {
280
          FieldIndex index = FieldIndex::ForDescriptor(map(), i);
281 282 283 284 285
          if (IsUnboxedDoubleField(index)) {
            os << "<unboxed double> " << RawFastDoublePropertyAt(index);
          } else {
            os << Brief(RawFastPropertyAt(index));
          }
286
          os << " (data field at offset " << index.property_index() << ")";
287 288
          break;
        }
289
        case ACCESSOR: {
290
          FieldIndex index = FieldIndex::ForDescriptor(map(), i);
291
          os << " (accessor field at offset " << index.property_index() << ")";
292 293
          break;
        }
294
        case DATA_CONSTANT:
295
          os << Brief(descs->GetConstant(i)) << " (data constant)";
296
          break;
297
        case ACCESSOR_CONSTANT:
298
          os << Brief(descs->GetCallbacksObject(i)) << " (accessor constant)";
299 300 301
          break;
      }
    }
302
  } else if (IsJSGlobalObject()) {
303
    global_dictionary()->Print(os);
304
  } else {
305
    property_dictionary()->Print(os);
306 307 308 309
  }
}


310
template <class T>
311
static void DoPrintElements(std::ostream& os, Object* object) {  // NOLINT
312 313
  T* p = T::cast(object);
  for (int i = 0; i < p->length(); i++) {
314
    os << "\n   " << i << ": " << p->get_scalar(i);
315 316 317 318
  }
}


319
void JSObject::PrintElements(std::ostream& os) {  // NOLINT
320 321 322
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
  switch (map()->elements_kind()) {
323 324 325
    case FAST_HOLEY_SMI_ELEMENTS:
    case FAST_SMI_ELEMENTS:
    case FAST_HOLEY_ELEMENTS:
326 327
    case FAST_ELEMENTS:
    case FAST_STRING_WRAPPER_ELEMENTS: {
328 329 330
      // Print in array notation for non-sparse arrays.
      FixedArray* p = FixedArray::cast(elements());
      for (int i = 0; i < p->length(); i++) {
331
        os << "\n   " << i << ": " << Brief(p->get(i));
332 333 334
      }
      break;
    }
335
    case FAST_HOLEY_DOUBLE_ELEMENTS:
336 337
    case FAST_DOUBLE_ELEMENTS: {
      // Print in array notation for non-sparse arrays.
338 339 340
      if (elements()->length() > 0) {
        FixedDoubleArray* p = FixedDoubleArray::cast(elements());
        for (int i = 0; i < p->length(); i++) {
341
          os << "\n   " << i << ": ";
342
          if (p->is_the_hole(i)) {
343
            os << "<the hole>";
344
          } else {
345
            os << p->get_scalar(i);
346
          }
347 348 349 350
        }
      }
      break;
    }
351 352


353 354 355 356 357
#define PRINT_ELEMENTS(Kind, Type)         \
  case Kind: {                             \
    DoPrintElements<Type>(os, elements()); \
    break;                                 \
  }
358 359 360 361 362 363 364 365

    PRINT_ELEMENTS(UINT8_ELEMENTS, FixedUint8Array)
    PRINT_ELEMENTS(UINT8_CLAMPED_ELEMENTS, FixedUint8ClampedArray)
    PRINT_ELEMENTS(INT8_ELEMENTS, FixedInt8Array)
    PRINT_ELEMENTS(UINT16_ELEMENTS, FixedUint16Array)
    PRINT_ELEMENTS(INT16_ELEMENTS, FixedInt16Array)
    PRINT_ELEMENTS(UINT32_ELEMENTS, FixedUint32Array)
    PRINT_ELEMENTS(INT32_ELEMENTS, FixedInt32Array)
366 367
    PRINT_ELEMENTS(FLOAT32_ELEMENTS, FixedFloat32Array)
    PRINT_ELEMENTS(FLOAT64_ELEMENTS, FixedFloat64Array)
368 369 370

#undef PRINT_ELEMENTS

371
    case DICTIONARY_ELEMENTS:
372
    case SLOW_STRING_WRAPPER_ELEMENTS:
373
      os << "\n - elements: ";
374
      elements()->Print(os);
375
      break;
376 377
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
378
      FixedArray* p = FixedArray::cast(elements());
379
      os << "\n   parameter map:";
380
      for (int i = 2; i < p->length(); i++) {
381
        os << " " << (i - 2) << ":" << Brief(p->get(i));
382
      }
383
      os << "\n   context: " << Brief(p->get(0))
384
         << "\n   arguments: " << Brief(p->get(1));
385 386
      break;
    }
387 388
    case NO_ELEMENTS:
      break;
389 390 391 392
  }
}


393 394 395
static void JSObjectPrintHeader(std::ostream& os, JSObject* obj,
                                const char* id) {  // NOLINT
  obj->PrintHeader(os, id);
396 397
  // Don't call GetElementsKind, its validation code can cause the printer to
  // fail when debugging.
398
  PrototypeIterator iter(obj->GetIsolate(), obj);
399
  os << "\n - map = " << reinterpret_cast<void*>(obj->map()) << " ["
400 401 402 403 404
     << ElementsKindToString(obj->map()->elements_kind())
     << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent());
}


405 406 407
static void JSObjectPrintBody(std::ostream& os, JSObject* obj,  // NOLINT
                              bool print_elements = true) {
  os << "\n {";
408 409
  obj->PrintProperties(os);
  obj->PrintTransitions(os);
410 411
  if (print_elements) obj->PrintElements(os);
  os << "\n }\n";
412 413 414
}


415 416 417 418 419 420
void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSObject");
  JSObjectPrintBody(os, this);
}


421 422 423 424 425 426 427
void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSRegExp");
  os << "\n - data = " << Brief(data());
  JSObjectPrintBody(os, this);
}


428
void JSModule::JSModulePrint(std::ostream& os) {  // NOLINT
429 430 431 432
  JSObjectPrintHeader(os, this, "JSModule");
  os << "\n - context = " << Brief(context());
  os << " - scope_info = " << Brief(scope_info());
  JSObjectPrintBody(os, this);
433 434 435
}


436
void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
437
  HeapObject::PrintHeader(os, "Symbol");
438
  os << "\n - hash: " << Hash();
439
  os << "\n - name: " << Brief(name());
440 441 442
  if (name()->IsUndefined()) {
    os << " (" << PrivateSymbolToName() << ")";
  }
443
  os << "\n - private: " << is_private();
444
  os << "\n";
445 446 447
}


448
void Map::MapPrint(std::ostream& os) {  // NOLINT
449
  HeapObject::PrintHeader(os, "Map");
450 451
  os << "\n - type: " << instance_type();
  os << "\n - instance size: " << instance_size();
452
  if (IsJSObjectMap()) {
453
    os << "\n - inobject properties: " << GetInObjectProperties();
454
  }
455 456 457 458 459
  os << "\n - elements kind: " << ElementsKindToString(elements_kind());
  os << "\n - unused property fields: " << unused_property_fields();
  if (is_deprecated()) os << "\n - deprecated_map";
  if (is_stable()) os << "\n - stable_map";
  if (is_dictionary_map()) os << "\n - dictionary_map";
460
  if (has_hidden_prototype()) os << "\n - has_hidden_prototype";
461 462 463 464 465 466 467 468 469
  if (has_named_interceptor()) os << " - named_interceptor";
  if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
  if (is_undetectable()) os << "\n - undetectable";
  if (is_callable()) os << "\n - callable";
  if (is_constructor()) os << "\n - constructor";
  if (is_access_check_needed()) os << "\n - access_check_needed";
  if (!is_extensible()) os << "\n - non-extensible";
  if (is_observed()) os << "\n - observed";
  if (is_strong()) os << "\n - strong_map";
470
  if (is_prototype_map()) {
471 472
    os << "\n - prototype_map";
    os << "\n - prototype info: " << Brief(prototype_info());
473
  } else {
474
    os << "\n - back pointer: " << Brief(GetBackPointer());
475
  }
476 477 478
  os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
     << "#" << NumberOfOwnDescriptors() << ": "
     << Brief(instance_descriptors());
479 480 481
  if (FLAG_unbox_double_fields) {
    os << "\n - layout descriptor: " << Brief(layout_descriptor());
  }
482 483 484 485 486
  int nof_transitions = TransitionArray::NumberOfTransitions(raw_transitions());
  if (nof_transitions > 0) {
    os << "\n - transitions #" << nof_transitions << ": "
       << Brief(raw_transitions());
    TransitionArray::PrintTransitions(os, raw_transitions(), false);
487
  }
488
  os << "\n - prototype: " << Brief(prototype());
489
  os << "\n - constructor: " << Brief(GetConstructor());
490 491
  os << "\n - code cache: " << Brief(code_cache());
  os << "\n - dependent code: " << Brief(dependent_code());
492
  os << "\n - construction counter: " << construction_counter();
493
  os << "\n";
494 495 496
}


497
void CodeCache::CodeCachePrint(std::ostream& os) {  // NOLINT
498 499 500
  HeapObject::PrintHeader(os, "CodeCache");
  os << "\n - default_cache: " << Brief(default_cache());
  os << "\n - normal_type_cache: " << Brief(normal_type_cache());
501 502 503
}


504 505
void PolymorphicCodeCache::PolymorphicCodeCachePrint(
    std::ostream& os) {  // NOLINT
506 507
  HeapObject::PrintHeader(os, "PolymorphicCodeCache");
  os << "\n - cache: " << Brief(cache());
508 509 510
}


511
void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) {  // NOLINT
512
  HeapObject::PrintHeader(os, "TypeFeedbackInfo");
513
  os << "\n - ic_total_count: " << ic_total_count()
514 515
     << ", ic_with_type_info_count: " << ic_with_type_info_count()
     << ", ic_generic_count: " << ic_generic_count() << "\n";
516 517 518
}


519 520
void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
    std::ostream& os) {  // NOLINT
521 522
  HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
  os << "\n - aliased_context_slot: " << aliased_context_slot();
523 524 525
}


526
void FixedArray::FixedArrayPrint(std::ostream& os) {  // NOLINT
527
  HeapObject::PrintHeader(os, "FixedArray");
528
  os << "\n - length: " << length();
529
  for (int i = 0; i < length(); i++) {
530
    os << "\n  [" << i << "]: " << Brief(get(i));
531
  }
532
  os << "\n";
533 534 535
}


536
void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
537
  HeapObject::PrintHeader(os, "FixedDoubleArray");
538
  os << "\n - length: " << length();
539
  for (int i = 0; i < length(); i++) {
540
    os << "\n  [" << i << "]: ";
541
    if (is_the_hole(i)) {
542
      os << "<the hole>";
543
    } else {
544
      os << get_scalar(i);
545
    }
546
  }
547
  os << "\n";
548 549 550
}


551 552
void TransitionArray::TransitionArrayPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TransitionArray");
553
  os << "\n - capacity: " << length();
554 555 556 557 558 559 560 561 562 563
  for (int i = 0; i < length(); i++) {
    os << "\n  [" << i << "]: " << Brief(get(i));
    if (i == kNextLinkIndex) os << " (next link)";
    if (i == kPrototypeTransitionsIndex) os << " (prototype transitions)";
    if (i == kTransitionLengthIndex) os << " (number of transitions)";
  }
  os << "\n";
}


564 565 566 567 568 569 570 571 572 573
void TypeFeedbackMetadata::Print() {
  OFStream os(stdout);
  TypeFeedbackMetadataPrint(os);
  os << std::flush;
}


void TypeFeedbackMetadata::TypeFeedbackMetadataPrint(
    std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TypeFeedbackMetadata");
574
  os << "\n - length: " << length();
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }

  TypeFeedbackMetadataIterator iter(this);
  while (iter.HasNext()) {
    FeedbackVectorSlot slot = iter.Next();
    FeedbackVectorSlotKind kind = iter.kind();
    os << "\n Slot " << slot << " " << kind;
  }
  os << "\n";
}


590 591 592 593 594 595 596 597 598
void TypeFeedbackVector::Print() {
  OFStream os(stdout);
  TypeFeedbackVectorPrint(os);
  os << std::flush;
}


void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "TypeFeedbackVector");
599
  os << "\n - length: " << length();
600 601 602 603 604
  if (length() == 0) {
    os << " (empty)\n";
    return;
  }

605
  TypeFeedbackMetadataIterator iter(metadata());
606 607 608 609
  while (iter.HasNext()) {
    FeedbackVectorSlot slot = iter.Next();
    FeedbackVectorSlotKind kind = iter.kind();

610
    os << "\n Slot " << slot << " " << kind << " ";
611 612 613 614 615 616 617 618 619 620
    switch (kind) {
      case FeedbackVectorSlotKind::LOAD_IC: {
        LoadICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
        KeyedLoadICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
621
      }
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
      case FeedbackVectorSlotKind::CALL_IC: {
        CallICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::STORE_IC: {
        StoreICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::KEYED_STORE_IC: {
        KeyedStoreICNexus nexus(this, slot);
        os << Code::ICState2String(nexus.StateFromFeedback());
        break;
      }
      case FeedbackVectorSlotKind::GENERAL:
        break;
      case FeedbackVectorSlotKind::INVALID:
      case FeedbackVectorSlotKind::KINDS_NUMBER:
        UNREACHABLE();
        break;
    }
644

645 646 647 648
    int entry_size = iter.entry_size();
    for (int i = 0; i < entry_size; i++) {
      int index = GetIndex(slot) + i;
      os << "\n  [" << index << "]: " << Brief(get(index));
649 650 651 652 653 654
    }
  }
  os << "\n";
}


655
void JSValue::JSValuePrint(std::ostream& os) {  // NOLINT
656 657 658
  JSObjectPrintHeader(os, this, "JSValue");
  os << "\n - value = " << Brief(value());
  JSObjectPrintBody(os, this);
659 660 661
}


662
void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
663 664
  JSObjectPrintHeader(os, this, "JSMessageObject");
  os << "\n - type: " << type();
665
  os << "\n - arguments: " << Brief(argument());
666 667 668 669
  os << "\n - start_position: " << start_position();
  os << "\n - end_position: " << end_position();
  os << "\n - script: " << Brief(script());
  os << "\n - stack_frames: " << Brief(stack_frames());
670
  JSObjectPrintBody(os, this);
671 672 673
}


674
void String::StringPrint(std::ostream& os) {  // NOLINT
675
  if (StringShape(this).IsInternalized()) {
676
    os << "#";
677
  } else if (StringShape(this).IsCons()) {
678
    os << "c\"";
679
  } else {
680
    os << "\"";
681 682 683 684 685 686 687 688 689 690
  }

  const char truncated_epilogue[] = "...<truncated>";
  int len = length();
  if (!FLAG_use_verbose_printer) {
    if (len > 100) {
      len = 100 - sizeof(truncated_epilogue);
    }
  }
  for (int i = 0; i < len; i++) {
691
    os << AsUC16(Get(i));
692 693
  }
  if (len != length()) {
694
    os << truncated_epilogue;
695 696
  }

697
  if (!StringShape(this).IsInternalized()) os << "\"";
698 699 700
}


701
void Name::NamePrint(std::ostream& os) {  // NOLINT
702
  if (IsString()) {
703
    String::cast(this)->StringPrint(os);
704 705 706
  } else if (IsSymbol()) {
    Symbol::cast(this)->name()->Print(os);
  } else {
707
    os << Brief(this);
708
  }
709 710 711
}


712 713 714 715
static const char* const weekdays[] = {
  "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};

716

717
void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
718 719
  JSObjectPrintHeader(os, this, "JSDate");
  os << "\n - value = " << Brief(value());
720
  if (!year()->IsSmi()) {
721
    os << "\n - time = NaN\n";
722
  } else {
723
    // TODO(svenpanne) Add some basic formatting to our streams.
724
    ScopedVector<char> buf(100);
725
    SNPrintF(
726
        buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
727 728 729 730 731 732 733 734
        weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0],
        year()->IsSmi() ? Smi::cast(year())->value() : -1,
        month()->IsSmi() ? Smi::cast(month())->value() : -1,
        day()->IsSmi() ? Smi::cast(day())->value() : -1,
        hour()->IsSmi() ? Smi::cast(hour())->value() : -1,
        min()->IsSmi() ? Smi::cast(min())->value() : -1,
        sec()->IsSmi() ? Smi::cast(sec())->value() : -1);
    os << buf.start();
735
  }
736
  JSObjectPrintBody(os, this);
737 738 739
}


740
void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
741
  HeapObject::PrintHeader(os, "JSProxy");
742
  os << "\n - map = " << reinterpret_cast<void*>(map());
743 744 745 746
  os << "\n - target = ";
  target()->ShortPrint(os);
  os << "\n - handler = ";
  handler()->ShortPrint(os);
747
  os << "\n - hash = ";
748
  hash()->ShortPrint(os);
749
  os << "\n";
750 751 752
}


753
void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
754
  JSObjectPrintHeader(os, this, "JSSet");
755
  os << " - table = " << Brief(table());
756
  JSObjectPrintBody(os, this);
757 758 759
}


760
void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
761
  JSObjectPrintHeader(os, this, "JSMap");
762
  os << " - table = " << Brief(table());
763
  JSObjectPrintBody(os, this);
764 765 766
}


767
template <class Derived, class TableType>
768 769 770
void
OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
    std::ostream& os) {  // NOLINT
771
  os << "\n - table = " << Brief(table());
772 773 774
  os << "\n - index = " << Brief(index());
  os << "\n - kind = " << Brief(kind());
  os << "\n";
775 776 777
}


778 779
template void OrderedHashTableIterator<
    JSSetIterator,
780
    OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
781 782


783 784
template void OrderedHashTableIterator<
    JSMapIterator,
785
    OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
786 787


788
void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
789
  JSObjectPrintHeader(os, this, "JSSetIterator");
790
  OrderedHashTableIteratorPrint(os);
791 792 793
}


794
void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
795
  JSObjectPrintHeader(os, this, "JSMapIterator");
796
  OrderedHashTableIteratorPrint(os);
797 798 799
}


800
void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
801 802 803
  JSObjectPrintHeader(os, this, "JSWeakMap");
  os << "\n - table = " << Brief(table());
  JSObjectPrintBody(os, this);
804 805 806
}


807
void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
808 809 810
  JSObjectPrintHeader(os, this, "JSWeakSet");
  os << "\n - table = " << Brief(table());
  JSObjectPrintBody(os, this);
811 812 813
}


814
void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
815 816 817
  JSObjectPrintHeader(os, this, "JSArrayBuffer");
  os << "\n - backing_store = " << backing_store();
  os << "\n - byte_length = " << Brief(byte_length());
818
  if (was_neutered()) os << " - neutered\n";
819
  JSObjectPrintBody(os, this, !was_neutered());
820 821 822
}


823
void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
824 825
  JSObjectPrintHeader(os, this, "JSTypedArray");
  os << "\n - buffer = " << Brief(buffer());
826 827 828
  os << "\n - byte_offset = " << Brief(byte_offset());
  os << "\n - byte_length = " << Brief(byte_length());
  os << "\n - length = " << Brief(length());
829
  if (WasNeutered()) os << " - neutered\n";
830
  JSObjectPrintBody(os, this, !WasNeutered());
831 832 833
}


834
void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
835 836
  JSObjectPrintHeader(os, this, "JSDataView");
  os << "\n - buffer =" << Brief(buffer());
837 838
  os << "\n - byte_offset = " << Brief(byte_offset());
  os << "\n - byte_length = " << Brief(byte_length());
839
  if (WasNeutered()) os << " - neutered\n";
840
  JSObjectPrintBody(os, this, !WasNeutered());
841 842 843
}


844 845 846 847 848 849 850 851 852
void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {  // NOLINT
  JSObjectPrintHeader(os, this, "JSBoundFunction");
  os << "\n - bound_target_function = " << Brief(bound_target_function());
  os << "\n - bound_this = " << Brief(bound_this());
  os << "\n - bound_arguments = " << Brief(bound_arguments());
  JSObjectPrintBody(os, this);
}


853
void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
854 855
  JSObjectPrintHeader(os, this, "Function");
  os << "\n - initial_map = ";
856 857
  if (has_initial_map()) os << Brief(initial_map());
  os << "\n - shared_info = " << Brief(shared());
858
  os << "\n - name = " << Brief(shared()->name());
859 860 861
  if (shared()->is_generator()) {
    os << "\n   - generator";
  }
862
  os << "\n - context = " << Brief(context());
863
  os << "\n - literals = " << Brief(literals());
864
  os << "\n - code = " << Brief(code());
865
  JSObjectPrintBody(os, this);
866 867 868
}


869
void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
870
  HeapObject::PrintHeader(os, "SharedFunctionInfo");
871
  os << "\n - name: " << Brief(name());
872 873 874 875 876
  os << "\n - expected_nof_properties: " << expected_nof_properties();
  os << "\n - ast_node_count: " << ast_node_count();
  os << "\n - instance class name = ";
  instance_class_name()->Print(os);
  os << "\n - code = " << Brief(code());
877
  if (HasSourceCode()) {
878
    os << "\n - source code = ";
879 880 881
    String* source = String::cast(Script::cast(script())->source());
    int start = start_position();
    int length = end_position() - start;
rmcilroy's avatar
rmcilroy committed
882 883
    base::SmartArrayPointer<char> source_string = source->ToCString(
        DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL);
884
    os << source_string.get();
885
  }
886
  // Script files are often large, hard to read.
887 888 889 890 891 892 893 894 895
  // os << "\n - script =";
  // script()->Print(os);
  os << "\n - function token position = " << function_token_position();
  os << "\n - start position = " << start_position();
  os << "\n - end position = " << end_position();
  os << "\n - is expression = " << is_expression();
  os << "\n - debug info = " << Brief(debug_info());
  os << "\n - length = " << length();
  os << "\n - optimized_code_map = " << Brief(optimized_code_map());
896 897
  os << "\n - feedback_vector = ";
  feedback_vector()->TypeFeedbackVectorPrint(os);
898 899 900
  if (HasBytecodeArray()) {
    os << "\n - bytecode_array = " << bytecode_array();
  }
901
  os << "\n";
902 903 904
}


905
void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
906 907 908 909
  os << "global_proxy ";
  JSObjectPrint(os);
  os << "native context : " << Brief(native_context());
  os << "\n";
910 911 912
}


913
void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
914 915 916 917
  os << "global ";
  JSObjectPrint(os);
  os << "native context : " << Brief(native_context());
  os << "\n";
918 919 920
}


921
void Cell::CellPrint(std::ostream& os) {  // NOLINT
922
  HeapObject::PrintHeader(os, "Cell");
923
  os << "\n - value: " << Brief(value());
924
  os << "\n";
925 926 927
}


928
void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
929
  HeapObject::PrintHeader(os, "PropertyCell");
930
  os << "\n - value: " << Brief(value());
931 932
  os << "\n - details: " << property_details();
  os << "\n";
933 934 935
}


ulan@chromium.org's avatar
ulan@chromium.org committed
936 937
void WeakCell::WeakCellPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "WeakCell");
938 939 940 941 942
  if (cleared()) {
    os << "\n - cleared";
  } else {
    os << "\n - value: " << Brief(value());
  }
943
  os << "\n";
ulan@chromium.org's avatar
ulan@chromium.org committed
944 945 946
}


947
void Code::CodePrint(std::ostream& os) {  // NOLINT
948
  HeapObject::PrintHeader(os, "Code");
949 950
#ifdef ENABLE_DISASSEMBLER
  if (FLAG_use_verbose_printer) {
951
    Disassemble(NULL, os);
952 953 954 955 956
  }
#endif
}


957
void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
958
  os << "foreign address : " << foreign_address();
959
  os << "\n";
960 961 962
}


963 964
void AccessorInfo::AccessorInfoPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "AccessorInfo");
965
  os << "\n - name: " << Brief(name());
966
  os << "\n - flag: " << flag();
967 968 969 970
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n - data: " << Brief(data());
  os << "\n";
971 972 973
}


974
void Box::BoxPrint(std::ostream& os) {  // NOLINT
975 976 977 978 979 980
  HeapObject::PrintHeader(os, "Box");
  os << "\n - value: " << Brief(value());
  os << "\n";
}


981 982 983
void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "PrototypeInfo");
  os << "\n - prototype users: " << Brief(prototype_users());
984
  os << "\n - registry slot: " << registry_slot();
985 986 987 988 989
  os << "\n - validity cell: " << Brief(validity_cell());
  os << "\n";
}


990 991 992 993 994 995 996 997 998
void SloppyBlockWithEvalContextExtension::
    SloppyBlockWithEvalContextExtensionPrint(std::ostream& os) {  // NOLINT
  HeapObject::PrintHeader(os, "SloppyBlockWithEvalContextExtension");
  os << "\n - scope_info: " << Brief(scope_info());
  os << "\n - extension: " << Brief(extension());
  os << "\n";
}


999
void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
1000 1001 1002 1003 1004 1005 1006
  HeapObject::PrintHeader(os, "AccessorPair");
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n";
}


1007
void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
1008 1009 1010
  HeapObject::PrintHeader(os, "AccessCheckInfo");
  os << "\n - named_callback: " << Brief(named_callback());
  os << "\n - indexed_callback: " << Brief(indexed_callback());
1011
  os << "\n - callback: " << Brief(callback());
1012 1013 1014 1015 1016
  os << "\n - data: " << Brief(data());
  os << "\n";
}


1017
void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
1018 1019 1020 1021 1022 1023 1024 1025
  HeapObject::PrintHeader(os, "InterceptorInfo");
  os << "\n - getter: " << Brief(getter());
  os << "\n - setter: " << Brief(setter());
  os << "\n - query: " << Brief(query());
  os << "\n - deleter: " << Brief(deleter());
  os << "\n - enumerator: " << Brief(enumerator());
  os << "\n - data: " << Brief(data());
  os << "\n";
1026 1027 1028
}


1029
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
1030 1031 1032 1033
  HeapObject::PrintHeader(os, "CallHandlerInfo");
  os << "\n - callback: " << Brief(callback());
  os << "\n - data: " << Brief(data());
  os << "\n";
1034 1035 1036
}


1037 1038
void FunctionTemplateInfo::FunctionTemplateInfoPrint(
    std::ostream& os) {  // NOLINT
1039 1040 1041
  HeapObject::PrintHeader(os, "FunctionTemplateInfo");
  os << "\n - class name: " << Brief(class_name());
  os << "\n - tag: " << Brief(tag());
1042
  os << "\n - serial_number: " << Brief(serial_number());
1043
  os << "\n - property_list: " << Brief(property_list());
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
  os << "\n - call_code: " << Brief(call_code());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - prototype_template: " << Brief(prototype_template());
  os << "\n - parent_template: " << Brief(parent_template());
  os << "\n - named_property_handler: " << Brief(named_property_handler());
  os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
  os << "\n - instance_template: " << Brief(instance_template());
  os << "\n - signature: " << Brief(signature());
  os << "\n - access_check_info: " << Brief(access_check_info());
  os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
  os << "\n - undetectable: " << (undetectable() ? "true" : "false");
  os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1056
  os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1057 1058 1059 1060
  os << "\n";
}


1061
void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
1062
  HeapObject::PrintHeader(os, "ObjectTemplateInfo");
1063 1064
  os << "\n - tag: " << Brief(tag());
  os << "\n - serial_number: " << Brief(serial_number());
1065 1066 1067 1068 1069 1070 1071 1072
  os << "\n - property_list: " << Brief(property_list());
  os << "\n - property_accessors: " << Brief(property_accessors());
  os << "\n - constructor: " << Brief(constructor());
  os << "\n - internal_field_count: " << Brief(internal_field_count());
  os << "\n";
}


1073
void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
1074
  HeapObject::PrintHeader(os, "AllocationSite");
1075
  os << "\n - weak_next: " << Brief(weak_next());
1076 1077 1078 1079 1080 1081 1082 1083 1084
  os << "\n - dependent code: " << Brief(dependent_code());
  os << "\n - nested site: " << Brief(nested_site());
  os << "\n - memento found count: "
     << Brief(Smi::FromInt(memento_found_count()));
  os << "\n - memento create count: "
     << Brief(Smi::FromInt(memento_create_count()));
  os << "\n - pretenure decision: "
     << Brief(Smi::FromInt(pretenure_decision()));
  os << "\n - transition_info: ";
1085 1086
  if (transition_info()->IsSmi()) {
    ElementsKind kind = GetElementsKind();
1087
    os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1088
  } else if (transition_info()->IsJSArray()) {
1089 1090 1091
    os << "Array literal " << Brief(transition_info());
  } else {
    os << "unknown transition_info" << Brief(transition_info());
1092
  }
1093
  os << "\n";
1094 1095 1096
}


1097
void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
1098
  HeapObject::PrintHeader(os, "AllocationMemento");
1099
  os << "\n - allocation site: ";
1100
  if (IsValid()) {
1101
    GetAllocationSite()->Print(os);
1102
  } else {
1103
    os << "<invalid>\n";
1104 1105 1106 1107
  }
}


1108
void Script::ScriptPrint(std::ostream& os) {  // NOLINT
1109 1110 1111
  HeapObject::PrintHeader(os, "Script");
  os << "\n - source: " << Brief(source());
  os << "\n - name: " << Brief(name());
1112 1113 1114 1115
  os << "\n - line_offset: " << line_offset();
  os << "\n - column_offset: " << column_offset();
  os << "\n - type: " << type();
  os << "\n - id: " << id();
1116 1117 1118 1119 1120 1121
  os << "\n - context data: " << Brief(context_data());
  os << "\n - wrapper: " << Brief(wrapper());
  os << "\n - compilation type: " << compilation_type();
  os << "\n - line ends: " << Brief(line_ends());
  os << "\n - eval from shared: " << Brief(eval_from_shared());
  os << "\n - eval from instructions offset: "
1122
     << eval_from_instructions_offset();
1123
  os << "\n - shared function infos: " << Brief(shared_function_infos());
1124 1125 1126 1127
  os << "\n";
}


1128
void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
1129 1130
  HeapObject::PrintHeader(os, "DebugInfo");
  os << "\n - shared: " << Brief(shared());
1131
  os << "\n - code: " << Brief(abstract_code());
1132 1133 1134 1135 1136
  os << "\n - break_points: ";
  break_points()->Print(os);
}


1137
void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) {  // NOLINT
1138
  HeapObject::PrintHeader(os, "BreakPointInfo");
1139
  os << "\n - code_offset: " << code_offset();
1140 1141
  os << "\n - source_position: " << source_position();
  os << "\n - statement_position: " << statement_position();
1142 1143 1144 1145 1146
  os << "\n - break_point_objects: " << Brief(break_point_objects());
  os << "\n";
}


1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
static void PrintBitMask(std::ostream& os, uint32_t value) {  // NOLINT
  for (int i = 0; i < 32; i++) {
    if ((i & 7) == 0) os << " ";
    os << (((value & 1) == 0) ? "_" : "x");
    value >>= 1;
  }
}


void LayoutDescriptor::Print() {
  OFStream os(stdout);
  this->Print(os);
  os << std::flush;
}


void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
  os << "Layout descriptor: ";
  if (IsUninitialized()) {
    os << "<uninitialized>";
  } else if (IsFastPointerLayout()) {
    os << "<all tagged>";
  } else if (IsSmi()) {
    os << "fast";
    PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
  } else {
    os << "slow";
1174
    int len = length();
1175 1176 1177 1178 1179 1180 1181 1182 1183
    for (int i = 0; i < len; i++) {
      if (i > 0) os << " |";
      PrintBitMask(os, get_scalar(i));
    }
  }
  os << "\n";
}


1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222
#endif  // OBJECT_PRINT


#if TRACE_MAPS


void Name::NameShortPrint() {
  if (this->IsString()) {
    PrintF("%s", String::cast(this)->ToCString().get());
  } else {
    DCHECK(this->IsSymbol());
    Symbol* s = Symbol::cast(this);
    if (s->name()->IsUndefined()) {
      PrintF("#<%s>", s->PrivateSymbolToName());
    } else {
      PrintF("<%s>", String::cast(s->name())->ToCString().get());
    }
  }
}


int Name::NameShortPrint(Vector<char> str) {
  if (this->IsString()) {
    return SNPrintF(str, "%s", String::cast(this)->ToCString().get());
  } else {
    DCHECK(this->IsSymbol());
    Symbol* s = Symbol::cast(this);
    if (s->name()->IsUndefined()) {
      return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
    } else {
      return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
    }
  }
}


#endif  // TRACE_MAPS


1223
#if defined(DEBUG) || defined(OBJECT_PRINT)
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
// This method is only meant to be called from gdb for debugging purposes.
// Since the string can also be in two-byte encoding, non-Latin1 characters
// will be ignored in the output.
char* String::ToAsciiArray() {
  // Static so that subsequent calls frees previously allocated space.
  // This also means that previous results will be overwritten.
  static char* buffer = NULL;
  if (buffer != NULL) delete[] buffer;
  buffer = new char[length() + 1];
  WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
  buffer[length()] = 0;
  return buffer;
}


void DescriptorArray::Print() {
  OFStream os(stdout);
  this->PrintDescriptors(os);
  os << std::flush;
}


void DescriptorArray::PrintDescriptors(std::ostream& os) {  // NOLINT
  HandleScope scope(GetIsolate());
1248
  os << "Descriptor array #" << number_of_descriptors();
1249 1250 1251
  for (int i = 0; i < number_of_descriptors(); i++) {
    Descriptor desc;
    Get(i, &desc);
1252
    os << "\n " << i << ": " << desc;
1253 1254 1255 1256 1257
  }
  os << "\n";
}


1258 1259
void TransitionArray::Print() {
  OFStream os(stdout);
1260
  TransitionArray::PrintTransitions(os, this);
1261
  os << "\n" << std::flush;
1262 1263 1264
}


1265
void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions,
1266
                                       bool print_header) {  // NOLINT
1267
  int num_transitions = NumberOfTransitions(transitions);
1268
  if (print_header) {
1269
    os << "Transition array #" << num_transitions << ":";
1270
  }
1271 1272 1273
  for (int i = 0; i < num_transitions; i++) {
    Name* key = GetKey(transitions, i);
    Map* target = GetTarget(transitions, i);
1274
    os << "\n   ";
1275
#ifdef OBJECT_PRINT
1276
    key->NamePrint(os);
1277 1278 1279
#else
    key->ShortPrint(os);
#endif
1280
    os << ": ";
1281 1282
    Heap* heap = key->GetHeap();
    if (key == heap->nonextensible_symbol()) {
1283
      os << "(transition to non-extensible)";
1284
    } else if (key == heap->sealed_symbol()) {
1285
      os << "(transition to sealed)";
1286
    } else if (key == heap->frozen_symbol()) {
1287
      os << "(transition to frozen)";
1288
    } else if (key == heap->elements_transition_symbol()) {
1289
      os << "(transition to " << ElementsKindToString(target->elements_kind())
1290
         << ")";
ishell's avatar
ishell committed
1291 1292 1293 1294
    } else if (key == heap->strict_function_transition_symbol()) {
      os << " (transition to strict function)";
    } else if (key == heap->strong_function_transition_symbol()) {
      os << " (transition to strong function)";
1295
    } else if (key == heap->observed_symbol()) {
1296 1297
      os << " (transition to Object.observe)";
    } else {
1298
      PropertyDetails details = GetTargetDetails(key, target);
1299
      os << "(transition to ";
1300
      if (details.location() == kDescriptor) {
1301 1302
        os << "immutable ";
      }
1303 1304
      os << (details.kind() == kData ? "data" : "accessor");
      if (details.location() == kDescriptor) {
1305 1306 1307
        Object* value =
            target->instance_descriptors()->GetValue(target->LastAdded());
        os << " " << Brief(value);
1308
      }
1309
      os << "), attrs: " << details.attributes();
1310
    }
1311
    os << " -> " << Brief(target);
1312 1313 1314 1315
  }
}


1316
void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
1317 1318 1319 1320 1321
  Object* transitions = map()->raw_transitions();
  int num_transitions = TransitionArray::NumberOfTransitions(transitions);
  if (num_transitions == 0) return;
  os << "\n - transitions";
  TransitionArray::PrintTransitions(os, transitions, false);
1322
}
1323
#endif  // defined(DEBUG) || defined(OBJECT_PRINT)
1324 1325
}  // namespace internal
}  // namespace v8