1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/objects.h"
6
7 #include <iomanip>
8 #include <memory>
9
10 #include "src/bootstrapper.h"
11 #include "src/disasm.h"
12 #include "src/disassembler.h"
13 #include "src/interpreter/bytecodes.h"
14 #include "src/objects-inl.h"
15 #include "src/ostreams.h"
16 #include "src/regexp/jsregexp.h"
17
18 namespace v8 {
19 namespace internal {
20
21 #ifdef OBJECT_PRINT
22
Print()23 void Object::Print() {
24 OFStream os(stdout);
25 this->Print(os);
26 os << std::flush;
27 }
28
29
Print(std::ostream & os)30 void Object::Print(std::ostream& os) { // NOLINT
31 if (IsSmi()) {
32 os << "Smi: " << std::hex << "0x" << Smi::cast(this)->value();
33 os << std::dec << " (" << Smi::cast(this)->value() << ")\n";
34 } else {
35 HeapObject::cast(this)->HeapObjectPrint(os);
36 }
37 }
38
39
PrintHeader(std::ostream & os,const char * id)40 void HeapObject::PrintHeader(std::ostream& os, const char* id) { // NOLINT
41 os << reinterpret_cast<void*>(this) << ": [";
42 if (id != nullptr) {
43 os << id;
44 } else {
45 os << map()->instance_type();
46 }
47 os << "]";
48 }
49
50
HeapObjectPrint(std::ostream & os)51 void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
52 InstanceType instance_type = map()->instance_type();
53
54 HandleScope scope(GetIsolate());
55 if (instance_type < FIRST_NONSTRING_TYPE) {
56 String::cast(this)->StringPrint(os);
57 os << "\n";
58 return;
59 }
60
61 switch (instance_type) {
62 case SYMBOL_TYPE:
63 Symbol::cast(this)->SymbolPrint(os);
64 break;
65 case MAP_TYPE:
66 Map::cast(this)->MapPrint(os);
67 break;
68 case HEAP_NUMBER_TYPE:
69 HeapNumber::cast(this)->HeapNumberPrint(os);
70 os << "\n";
71 break;
72 case MUTABLE_HEAP_NUMBER_TYPE:
73 os << "<mutable ";
74 HeapNumber::cast(this)->HeapNumberPrint(os);
75 os << ">\n";
76 break;
77 case FIXED_DOUBLE_ARRAY_TYPE:
78 FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
79 break;
80 case FIXED_ARRAY_TYPE:
81 FixedArray::cast(this)->FixedArrayPrint(os);
82 break;
83 case BYTE_ARRAY_TYPE:
84 ByteArray::cast(this)->ByteArrayPrint(os);
85 break;
86 case BYTECODE_ARRAY_TYPE:
87 BytecodeArray::cast(this)->BytecodeArrayPrint(os);
88 break;
89 case TRANSITION_ARRAY_TYPE:
90 TransitionArray::cast(this)->TransitionArrayPrint(os);
91 break;
92 case FREE_SPACE_TYPE:
93 FreeSpace::cast(this)->FreeSpacePrint(os);
94 break;
95
96 #define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
97 case Fixed##Type##Array::kInstanceType: \
98 Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os); \
99 break;
100
101 TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
102 #undef PRINT_FIXED_TYPED_ARRAY
103
104 case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
105 case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
106 case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
107 case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
108 case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
109 case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
110 case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
111 case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
112 case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
113 case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
114 case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
115 case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
116 case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
117 case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
118 case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
119 case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
120 case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
121 case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
122 case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
123 case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
124 case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
125 case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
126 case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
127 case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
128 case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
129 case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
130 case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
131 case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
132 case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
133 case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
134 case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
135 case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
136 case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
137 case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
138 case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
139 JSArrayIterator::cast(this)->JSArrayIteratorPrint(os);
140 break;
141
142 case FILLER_TYPE:
143 os << "filler";
144 break;
145 case JS_OBJECT_TYPE: // fall through
146 case JS_API_OBJECT_TYPE:
147 case JS_SPECIAL_API_OBJECT_TYPE:
148 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
149 case JS_GENERATOR_OBJECT_TYPE:
150 case JS_ARGUMENTS_TYPE:
151 case JS_ERROR_TYPE:
152 case JS_PROMISE_CAPABILITY_TYPE:
153 JSObject::cast(this)->JSObjectPrint(os);
154 break;
155 case JS_PROMISE_TYPE:
156 JSPromise::cast(this)->JSPromisePrint(os);
157 break;
158 case JS_ARRAY_TYPE:
159 JSArray::cast(this)->JSArrayPrint(os);
160 break;
161 case JS_REGEXP_TYPE:
162 JSRegExp::cast(this)->JSRegExpPrint(os);
163 break;
164 case ODDBALL_TYPE:
165 Oddball::cast(this)->to_string()->Print(os);
166 break;
167 case JS_BOUND_FUNCTION_TYPE:
168 JSBoundFunction::cast(this)->JSBoundFunctionPrint(os);
169 break;
170 case JS_FUNCTION_TYPE:
171 JSFunction::cast(this)->JSFunctionPrint(os);
172 break;
173 case JS_GLOBAL_PROXY_TYPE:
174 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
175 break;
176 case JS_GLOBAL_OBJECT_TYPE:
177 JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
178 break;
179 case JS_VALUE_TYPE:
180 JSValue::cast(this)->JSValuePrint(os);
181 break;
182 case JS_DATE_TYPE:
183 JSDate::cast(this)->JSDatePrint(os);
184 break;
185 case CODE_TYPE:
186 Code::cast(this)->CodePrint(os);
187 break;
188 case JS_PROXY_TYPE:
189 JSProxy::cast(this)->JSProxyPrint(os);
190 break;
191 case JS_SET_TYPE:
192 JSSet::cast(this)->JSSetPrint(os);
193 break;
194 case JS_MAP_TYPE:
195 JSMap::cast(this)->JSMapPrint(os);
196 break;
197 case JS_SET_ITERATOR_TYPE:
198 JSSetIterator::cast(this)->JSSetIteratorPrint(os);
199 break;
200 case JS_MAP_ITERATOR_TYPE:
201 JSMapIterator::cast(this)->JSMapIteratorPrint(os);
202 break;
203 case JS_WEAK_MAP_TYPE:
204 JSWeakMap::cast(this)->JSWeakMapPrint(os);
205 break;
206 case JS_WEAK_SET_TYPE:
207 JSWeakSet::cast(this)->JSWeakSetPrint(os);
208 break;
209 case JS_MODULE_NAMESPACE_TYPE:
210 JSModuleNamespace::cast(this)->JSModuleNamespacePrint(os);
211 break;
212 case FOREIGN_TYPE:
213 Foreign::cast(this)->ForeignPrint(os);
214 break;
215 case SHARED_FUNCTION_INFO_TYPE:
216 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
217 break;
218 case JS_MESSAGE_OBJECT_TYPE:
219 JSMessageObject::cast(this)->JSMessageObjectPrint(os);
220 break;
221 case CELL_TYPE:
222 Cell::cast(this)->CellPrint(os);
223 break;
224 case PROPERTY_CELL_TYPE:
225 PropertyCell::cast(this)->PropertyCellPrint(os);
226 break;
227 case WEAK_CELL_TYPE:
228 WeakCell::cast(this)->WeakCellPrint(os);
229 break;
230 case JS_ARRAY_BUFFER_TYPE:
231 JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
232 break;
233 case JS_TYPED_ARRAY_TYPE:
234 JSTypedArray::cast(this)->JSTypedArrayPrint(os);
235 break;
236 case JS_DATA_VIEW_TYPE:
237 JSDataView::cast(this)->JSDataViewPrint(os);
238 break;
239 #define MAKE_STRUCT_CASE(NAME, Name, name) \
240 case NAME##_TYPE: \
241 Name::cast(this)->Name##Print(os); \
242 break;
243 STRUCT_LIST(MAKE_STRUCT_CASE)
244 #undef MAKE_STRUCT_CASE
245
246 default:
247 os << "UNKNOWN TYPE " << map()->instance_type();
248 UNREACHABLE();
249 break;
250 }
251 }
252
ByteArrayPrint(std::ostream & os)253 void ByteArray::ByteArrayPrint(std::ostream& os) { // NOLINT
254 os << "byte array, data starts at " << GetDataStartAddress();
255 }
256
257
BytecodeArrayPrint(std::ostream & os)258 void BytecodeArray::BytecodeArrayPrint(std::ostream& os) { // NOLINT
259 Disassemble(os);
260 }
261
262
FreeSpacePrint(std::ostream & os)263 void FreeSpace::FreeSpacePrint(std::ostream& os) { // NOLINT
264 os << "free space, size " << Size();
265 }
266
267
268 template <class Traits>
FixedTypedArrayPrint(std::ostream & os)269 void FixedTypedArray<Traits>::FixedTypedArrayPrint(
270 std::ostream& os) { // NOLINT
271 os << "fixed " << Traits::Designator();
272 }
273
PrintProperties(std::ostream & os)274 bool JSObject::PrintProperties(std::ostream& os) { // NOLINT
275 if (HasFastProperties()) {
276 DescriptorArray* descs = map()->instance_descriptors();
277 int i = 0;
278 for (; i < map()->NumberOfOwnDescriptors(); i++) {
279 os << "\n ";
280 descs->GetKey(i)->NamePrint(os);
281 os << ": ";
282 PropertyDetails details = descs->GetDetails(i);
283 switch (details.location()) {
284 case kField: {
285 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
286 if (IsUnboxedDoubleField(field_index)) {
287 os << "<unboxed double> " << RawFastDoublePropertyAt(field_index);
288 } else {
289 os << Brief(RawFastPropertyAt(field_index));
290 }
291 break;
292 }
293 case kDescriptor:
294 os << Brief(descs->GetValue(i));
295 break;
296 }
297 os << " ";
298 details.PrintAsFastTo(os, PropertyDetails::kForProperties);
299 }
300 return i > 0;
301 } else if (IsJSGlobalObject()) {
302 global_dictionary()->Print(os);
303 } else {
304 property_dictionary()->Print(os);
305 }
306 return true;
307 }
308
309 namespace {
310
311 template <class T>
IsTheHoleAt(T * array,int index)312 bool IsTheHoleAt(T* array, int index) {
313 return false;
314 }
315
316 template <>
IsTheHoleAt(FixedDoubleArray * array,int index)317 bool IsTheHoleAt(FixedDoubleArray* array, int index) {
318 return array->is_the_hole(index);
319 }
320
321 template <class T>
GetScalarElement(T * array,int index)322 double GetScalarElement(T* array, int index) {
323 if (IsTheHoleAt(array, index)) {
324 return std::numeric_limits<double>::quiet_NaN();
325 }
326 return array->get_scalar(index);
327 }
328
329 template <class T>
DoPrintElements(std::ostream & os,Object * object)330 void DoPrintElements(std::ostream& os, Object* object) { // NOLINT
331 const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value;
332 T* array = T::cast(object);
333 if (array->length() == 0) return;
334 int previous_index = 0;
335 double previous_value = GetScalarElement(array, 0);
336 double value = 0.0;
337 int i;
338 for (i = 1; i <= array->length(); i++) {
339 if (i < array->length()) value = GetScalarElement(array, i);
340 bool values_are_nan = std::isnan(previous_value) && std::isnan(value);
341 if (i != array->length() && (previous_value == value || values_are_nan) &&
342 IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) {
343 continue;
344 }
345 os << "\n";
346 std::stringstream ss;
347 ss << previous_index;
348 if (previous_index != i - 1) {
349 ss << '-' << (i - 1);
350 }
351 os << std::setw(12) << ss.str() << ": ";
352 if (print_the_hole && IsTheHoleAt(array, i - 1)) {
353 os << "<the_hole>";
354 } else {
355 os << previous_value;
356 }
357 previous_index = i;
358 previous_value = value;
359 }
360 }
361
PrintFixedArrayElements(std::ostream & os,FixedArray * array)362 void PrintFixedArrayElements(std::ostream& os, FixedArray* array) {
363 // Print in array notation for non-sparse arrays.
364 Object* previous_value = array->length() > 0 ? array->get(0) : nullptr;
365 Object* value = nullptr;
366 int previous_index = 0;
367 int i;
368 for (i = 1; i <= array->length(); i++) {
369 if (i < array->length()) value = array->get(i);
370 if (previous_value == value && i != array->length()) {
371 continue;
372 }
373 os << "\n";
374 std::stringstream ss;
375 ss << previous_index;
376 if (previous_index != i - 1) {
377 ss << '-' << (i - 1);
378 }
379 os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
380 previous_index = i;
381 previous_value = value;
382 }
383 }
384
385 } // namespace
386
PrintElements(std::ostream & os)387 bool JSObject::PrintElements(std::ostream& os) { // NOLINT
388 // Don't call GetElementsKind, its validation code can cause the printer to
389 // fail when debugging.
390 if (elements()->length() == 0) return false;
391 switch (map()->elements_kind()) {
392 case FAST_HOLEY_SMI_ELEMENTS:
393 case FAST_SMI_ELEMENTS:
394 case FAST_HOLEY_ELEMENTS:
395 case FAST_ELEMENTS:
396 case FAST_STRING_WRAPPER_ELEMENTS: {
397 PrintFixedArrayElements(os, FixedArray::cast(elements()));
398 break;
399 }
400 case FAST_HOLEY_DOUBLE_ELEMENTS:
401 case FAST_DOUBLE_ELEMENTS: {
402 DoPrintElements<FixedDoubleArray>(os, elements());
403 break;
404 }
405
406 #define PRINT_ELEMENTS(Type, type, TYPE, elementType, size) \
407 case TYPE##_ELEMENTS: { \
408 DoPrintElements<Fixed##Type##Array>(os, elements()); \
409 break; \
410 }
411 TYPED_ARRAYS(PRINT_ELEMENTS)
412 #undef PRINT_ELEMENTS
413
414 case DICTIONARY_ELEMENTS:
415 case SLOW_STRING_WRAPPER_ELEMENTS:
416 SeededNumberDictionary::cast(elements())->Print(os);
417 break;
418 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
419 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
420 FixedArray* p = FixedArray::cast(elements());
421 os << "\n parameter map:";
422 for (int i = 2; i < p->length(); i++) {
423 os << " " << (i - 2) << ":" << Brief(p->get(i));
424 }
425 os << "\n context: " << Brief(p->get(0))
426 << "\n arguments: " << Brief(p->get(1));
427 break;
428 }
429 case NO_ELEMENTS:
430 break;
431 }
432 return true;
433 }
434
435
JSObjectPrintHeader(std::ostream & os,JSObject * obj,const char * id)436 static void JSObjectPrintHeader(std::ostream& os, JSObject* obj,
437 const char* id) { // NOLINT
438 obj->PrintHeader(os, id);
439 // Don't call GetElementsKind, its validation code can cause the printer to
440 // fail when debugging.
441 os << "\n - map = " << reinterpret_cast<void*>(obj->map()) << " [";
442 if (obj->HasFastProperties()) {
443 os << "FastProperties";
444 } else {
445 os << "DictionaryProperties";
446 }
447 PrototypeIterator iter(obj->GetIsolate(), obj);
448 os << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent());
449 os << "\n - elements = " << Brief(obj->elements()) << " ["
450 << ElementsKindToString(obj->map()->elements_kind());
451 if (obj->elements()->map() == obj->GetHeap()->fixed_cow_array_map()) {
452 os << " (COW)";
453 }
454 os << "]";
455 if (obj->GetInternalFieldCount() > 0) {
456 os << "\n - internal fields: " << obj->GetInternalFieldCount();
457 }
458 }
459
460
JSObjectPrintBody(std::ostream & os,JSObject * obj,bool print_elements=true)461 static void JSObjectPrintBody(std::ostream& os, JSObject* obj, // NOLINT
462 bool print_elements = true) {
463 os << "\n - properties = " << Brief(obj->properties()) << " {";
464 if (obj->PrintProperties(os)) os << "\n ";
465 os << "}\n";
466 if (print_elements && obj->elements()->length() > 0) {
467 os << " - elements = " << Brief(obj->elements()) << " {";
468 if (obj->PrintElements(os)) os << "\n ";
469 os << "}\n";
470 }
471 int internal_fields = obj->GetInternalFieldCount();
472 if (internal_fields > 0) {
473 os << " - internal fields = {";
474 for (int i = 0; i < internal_fields; i++) {
475 os << "\n " << obj->GetInternalField(i);
476 }
477 os << "\n }\n";
478 }
479 }
480
481
JSObjectPrint(std::ostream & os)482 void JSObject::JSObjectPrint(std::ostream& os) { // NOLINT
483 JSObjectPrintHeader(os, this, nullptr);
484 JSObjectPrintBody(os, this);
485 }
486
JSArrayPrint(std::ostream & os)487 void JSArray::JSArrayPrint(std::ostream& os) { // NOLINT
488 JSObjectPrintHeader(os, this, "JSArray");
489 os << "\n - length = " << Brief(this->length());
490 JSObjectPrintBody(os, this);
491 }
492
JSPromisePrint(std::ostream & os)493 void JSPromise::JSPromisePrint(std::ostream& os) { // NOLINT
494 JSObjectPrintHeader(os, this, "JSPromise");
495 os << "\n - status = " << JSPromise::Status(status());
496 os << "\n - result = " << Brief(result());
497 os << "\n - deferred_promise: " << Brief(deferred_promise());
498 os << "\n - deferred_on_resolve: " << Brief(deferred_on_resolve());
499 os << "\n - deferred_on_reject: " << Brief(deferred_on_reject());
500 os << "\n - fulfill_reactions = " << Brief(fulfill_reactions());
501 os << "\n - reject_reactions = " << Brief(reject_reactions());
502 os << "\n - has_handler = " << has_handler();
503 os << "\n ";
504 }
505
JSRegExpPrint(std::ostream & os)506 void JSRegExp::JSRegExpPrint(std::ostream& os) { // NOLINT
507 JSObjectPrintHeader(os, this, "JSRegExp");
508 os << "\n - data = " << Brief(data());
509 JSObjectPrintBody(os, this);
510 }
511
512
SymbolPrint(std::ostream & os)513 void Symbol::SymbolPrint(std::ostream& os) { // NOLINT
514 HeapObject::PrintHeader(os, "Symbol");
515 os << "\n - hash: " << Hash();
516 os << "\n - name: " << Brief(name());
517 if (name()->IsUndefined(GetIsolate())) {
518 os << " (" << PrivateSymbolToName() << ")";
519 }
520 os << "\n - private: " << is_private();
521 os << "\n";
522 }
523
524
MapPrint(std::ostream & os)525 void Map::MapPrint(std::ostream& os) { // NOLINT
526 HeapObject::PrintHeader(os, "Map");
527 os << "\n - type: " << instance_type();
528 os << "\n - instance size: " << instance_size();
529 if (IsJSObjectMap()) {
530 os << "\n - inobject properties: " << GetInObjectProperties();
531 }
532 os << "\n - elements kind: " << ElementsKindToString(elements_kind());
533 os << "\n - unused property fields: " << unused_property_fields();
534 os << "\n - enum length: ";
535 if (EnumLength() == kInvalidEnumCacheSentinel) {
536 os << "invalid";
537 } else {
538 os << EnumLength();
539 }
540 if (is_deprecated()) os << "\n - deprecated_map";
541 if (is_stable()) os << "\n - stable_map";
542 if (is_migration_target()) os << "\n - migration_target";
543 if (is_dictionary_map()) os << "\n - dictionary_map";
544 if (has_hidden_prototype()) os << "\n - has_hidden_prototype";
545 if (has_named_interceptor()) os << "\n - named_interceptor";
546 if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
547 if (is_undetectable()) os << "\n - undetectable";
548 if (is_callable()) os << "\n - callable";
549 if (is_constructor()) os << "\n - constructor";
550 if (is_access_check_needed()) os << "\n - access_check_needed";
551 if (!is_extensible()) os << "\n - non-extensible";
552 if (is_prototype_map()) {
553 os << "\n - prototype_map";
554 os << "\n - prototype info: " << Brief(prototype_info());
555 } else {
556 os << "\n - back pointer: " << Brief(GetBackPointer());
557 }
558 os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
559 << "#" << NumberOfOwnDescriptors() << ": "
560 << Brief(instance_descriptors());
561 if (FLAG_unbox_double_fields) {
562 os << "\n - layout descriptor: ";
563 layout_descriptor()->ShortPrint(os);
564 }
565 int nof_transitions = TransitionArray::NumberOfTransitions(raw_transitions());
566 if (nof_transitions > 0) {
567 os << "\n - transitions #" << nof_transitions << ": "
568 << Brief(raw_transitions());
569 TransitionArray::PrintTransitions(os, raw_transitions(), false);
570 }
571 os << "\n - prototype: " << Brief(prototype());
572 os << "\n - constructor: " << Brief(GetConstructor());
573 os << "\n - code cache: " << Brief(code_cache());
574 os << "\n - dependent code: " << Brief(dependent_code());
575 os << "\n - construction counter: " << construction_counter();
576 os << "\n";
577 }
578
579
TypeFeedbackInfoPrint(std::ostream & os)580 void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) { // NOLINT
581 HeapObject::PrintHeader(os, "TypeFeedbackInfo");
582 os << "\n - ic_total_count: " << ic_total_count()
583 << ", ic_with_type_info_count: " << ic_with_type_info_count()
584 << ", ic_generic_count: " << ic_generic_count() << "\n";
585 }
586
587
AliasedArgumentsEntryPrint(std::ostream & os)588 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
589 std::ostream& os) { // NOLINT
590 HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
591 os << "\n - aliased_context_slot: " << aliased_context_slot();
592 }
593
594
FixedArrayPrint(std::ostream & os)595 void FixedArray::FixedArrayPrint(std::ostream& os) { // NOLINT
596 HeapObject::PrintHeader(os, "FixedArray");
597 os << "\n - map = " << Brief(map());
598 os << "\n - length: " << length();
599 PrintFixedArrayElements(os, this);
600 os << "\n";
601 }
602
603
FixedDoubleArrayPrint(std::ostream & os)604 void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) { // NOLINT
605 HeapObject::PrintHeader(os, "FixedDoubleArray");
606 os << "\n - map = " << Brief(map());
607 os << "\n - length: " << length();
608 DoPrintElements<FixedDoubleArray>(os, this);
609 os << "\n";
610 }
611
612
TransitionArrayPrint(std::ostream & os)613 void TransitionArray::TransitionArrayPrint(std::ostream& os) { // NOLINT
614 HeapObject::PrintHeader(os, "TransitionArray");
615 os << "\n - capacity: " << length();
616 for (int i = 0; i < length(); i++) {
617 os << "\n [" << i << "]: " << Brief(get(i));
618 if (i == kNextLinkIndex) os << " (next link)";
619 if (i == kPrototypeTransitionsIndex) os << " (prototype transitions)";
620 if (i == kTransitionLengthIndex) os << " (number of transitions)";
621 }
622 os << "\n";
623 }
624
625 template void FeedbackVectorSpecBase<StaticFeedbackVectorSpec>::Print();
626 template void FeedbackVectorSpecBase<FeedbackVectorSpec>::Print();
627
628 template <typename Derived>
Print()629 void FeedbackVectorSpecBase<Derived>::Print() {
630 OFStream os(stdout);
631 FeedbackVectorSpecPrint(os);
632 os << std::flush;
633 }
634
635 template <typename Derived>
FeedbackVectorSpecPrint(std::ostream & os)636 void FeedbackVectorSpecBase<Derived>::FeedbackVectorSpecPrint(
637 std::ostream& os) { // NOLINT
638 int slot_count = This()->slots();
639 os << " - slot_count: " << slot_count;
640 if (slot_count == 0) {
641 os << " (empty)\n";
642 return;
643 }
644
645 for (int slot = 0; slot < slot_count;) {
646 FeedbackSlotKind kind = This()->GetKind(FeedbackSlot(slot));
647 int entry_size = FeedbackMetadata::GetSlotSize(kind);
648 DCHECK_LT(0, entry_size);
649 os << "\n Slot #" << slot << " " << kind;
650 slot += entry_size;
651 }
652 os << "\n";
653 }
654
Print()655 void FeedbackMetadata::Print() {
656 OFStream os(stdout);
657 FeedbackMetadataPrint(os);
658 os << std::flush;
659 }
660
FeedbackMetadataPrint(std::ostream & os)661 void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) { // NOLINT
662 HeapObject::PrintHeader(os, "FeedbackMetadata");
663 os << "\n - length: " << length();
664 if (length() == 0) {
665 os << " (empty)\n";
666 return;
667 }
668 os << "\n - slot_count: " << slot_count();
669
670 FeedbackMetadataIterator iter(this);
671 while (iter.HasNext()) {
672 FeedbackSlot slot = iter.Next();
673 FeedbackSlotKind kind = iter.kind();
674 os << "\n Slot " << slot << " " << kind;
675 }
676 os << "\n";
677 }
678
Print()679 void FeedbackVector::Print() {
680 OFStream os(stdout);
681 FeedbackVectorPrint(os);
682 os << std::flush;
683 }
684
FeedbackVectorPrint(std::ostream & os)685 void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
686 HeapObject::PrintHeader(os, "FeedbackVector");
687 os << "\n - length: " << length();
688 if (length() == 0) {
689 os << " (empty)\n";
690 return;
691 }
692
693 FeedbackMetadataIterator iter(metadata());
694 while (iter.HasNext()) {
695 FeedbackSlot slot = iter.Next();
696 FeedbackSlotKind kind = iter.kind();
697
698 os << "\n Slot " << slot << " " << kind;
699 os << " ";
700 switch (kind) {
701 case FeedbackSlotKind::kLoadProperty: {
702 LoadICNexus nexus(this, slot);
703 os << Code::ICState2String(nexus.StateFromFeedback());
704 break;
705 }
706 case FeedbackSlotKind::kLoadGlobalInsideTypeof:
707 case FeedbackSlotKind::kLoadGlobalNotInsideTypeof: {
708 LoadGlobalICNexus nexus(this, slot);
709 os << Code::ICState2String(nexus.StateFromFeedback());
710 break;
711 }
712 case FeedbackSlotKind::kLoadKeyed: {
713 KeyedLoadICNexus nexus(this, slot);
714 os << Code::ICState2String(nexus.StateFromFeedback());
715 break;
716 }
717 case FeedbackSlotKind::kCall: {
718 CallICNexus nexus(this, slot);
719 os << Code::ICState2String(nexus.StateFromFeedback());
720 break;
721 }
722 case FeedbackSlotKind::kStoreNamedSloppy:
723 case FeedbackSlotKind::kStoreNamedStrict:
724 case FeedbackSlotKind::kStoreOwnNamed: {
725 StoreICNexus nexus(this, slot);
726 os << Code::ICState2String(nexus.StateFromFeedback());
727 break;
728 }
729 case FeedbackSlotKind::kStoreKeyedSloppy:
730 case FeedbackSlotKind::kStoreKeyedStrict: {
731 KeyedStoreICNexus nexus(this, slot);
732 os << Code::ICState2String(nexus.StateFromFeedback());
733 break;
734 }
735 case FeedbackSlotKind::kBinaryOp: {
736 BinaryOpICNexus nexus(this, slot);
737 os << Code::ICState2String(nexus.StateFromFeedback());
738 break;
739 }
740 case FeedbackSlotKind::kCompareOp: {
741 CompareICNexus nexus(this, slot);
742 os << Code::ICState2String(nexus.StateFromFeedback());
743 break;
744 }
745 case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
746 StoreDataPropertyInLiteralICNexus nexus(this, slot);
747 os << Code::ICState2String(nexus.StateFromFeedback());
748 break;
749 }
750 case FeedbackSlotKind::kCreateClosure:
751 case FeedbackSlotKind::kLiteral:
752 case FeedbackSlotKind::kGeneral:
753 break;
754 case FeedbackSlotKind::kToBoolean:
755 case FeedbackSlotKind::kInvalid:
756 case FeedbackSlotKind::kKindsNumber:
757 UNREACHABLE();
758 break;
759 }
760
761 int entry_size = iter.entry_size();
762 for (int i = 0; i < entry_size; i++) {
763 int index = GetIndex(slot) + i;
764 os << "\n [" << index << "]: " << Brief(get(index));
765 }
766 }
767 os << "\n";
768 }
769
770
JSValuePrint(std::ostream & os)771 void JSValue::JSValuePrint(std::ostream& os) { // NOLINT
772 JSObjectPrintHeader(os, this, "JSValue");
773 os << "\n - value = " << Brief(value());
774 JSObjectPrintBody(os, this);
775 }
776
777
JSMessageObjectPrint(std::ostream & os)778 void JSMessageObject::JSMessageObjectPrint(std::ostream& os) { // NOLINT
779 JSObjectPrintHeader(os, this, "JSMessageObject");
780 os << "\n - type: " << type();
781 os << "\n - arguments: " << Brief(argument());
782 os << "\n - start_position: " << start_position();
783 os << "\n - end_position: " << end_position();
784 os << "\n - script: " << Brief(script());
785 os << "\n - stack_frames: " << Brief(stack_frames());
786 JSObjectPrintBody(os, this);
787 }
788
789
StringPrint(std::ostream & os)790 void String::StringPrint(std::ostream& os) { // NOLINT
791 if (StringShape(this).IsInternalized()) {
792 os << "#";
793 } else if (StringShape(this).IsCons()) {
794 os << "c\"";
795 } else if (StringShape(this).IsThin()) {
796 os << ">\"";
797 } else {
798 os << "\"";
799 }
800
801 const char truncated_epilogue[] = "...<truncated>";
802 int len = length();
803 if (!FLAG_use_verbose_printer) {
804 if (len > 100) {
805 len = 100 - sizeof(truncated_epilogue);
806 }
807 }
808 for (int i = 0; i < len; i++) {
809 os << AsUC16(Get(i));
810 }
811 if (len != length()) {
812 os << truncated_epilogue;
813 }
814
815 if (!StringShape(this).IsInternalized()) os << "\"";
816 }
817
818
NamePrint(std::ostream & os)819 void Name::NamePrint(std::ostream& os) { // NOLINT
820 if (IsString()) {
821 String::cast(this)->StringPrint(os);
822 } else {
823 os << Brief(this);
824 }
825 }
826
827
828 static const char* const weekdays[] = {
829 "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
830 };
831
832
JSDatePrint(std::ostream & os)833 void JSDate::JSDatePrint(std::ostream& os) { // NOLINT
834 JSObjectPrintHeader(os, this, "JSDate");
835 os << "\n - value = " << Brief(value());
836 if (!year()->IsSmi()) {
837 os << "\n - time = NaN\n";
838 } else {
839 // TODO(svenpanne) Add some basic formatting to our streams.
840 ScopedVector<char> buf(100);
841 SNPrintF(
842 buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
843 weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0],
844 year()->IsSmi() ? Smi::cast(year())->value() : -1,
845 month()->IsSmi() ? Smi::cast(month())->value() : -1,
846 day()->IsSmi() ? Smi::cast(day())->value() : -1,
847 hour()->IsSmi() ? Smi::cast(hour())->value() : -1,
848 min()->IsSmi() ? Smi::cast(min())->value() : -1,
849 sec()->IsSmi() ? Smi::cast(sec())->value() : -1);
850 os << buf.start();
851 }
852 JSObjectPrintBody(os, this);
853 }
854
855
JSProxyPrint(std::ostream & os)856 void JSProxy::JSProxyPrint(std::ostream& os) { // NOLINT
857 HeapObject::PrintHeader(os, "JSProxy");
858 os << "\n - map = " << reinterpret_cast<void*>(map());
859 os << "\n - target = ";
860 target()->ShortPrint(os);
861 os << "\n - handler = ";
862 handler()->ShortPrint(os);
863 os << "\n - hash = ";
864 hash()->ShortPrint(os);
865 os << "\n";
866 }
867
868
JSSetPrint(std::ostream & os)869 void JSSet::JSSetPrint(std::ostream& os) { // NOLINT
870 JSObjectPrintHeader(os, this, "JSSet");
871 os << " - table = " << Brief(table());
872 JSObjectPrintBody(os, this);
873 }
874
875
JSMapPrint(std::ostream & os)876 void JSMap::JSMapPrint(std::ostream& os) { // NOLINT
877 JSObjectPrintHeader(os, this, "JSMap");
878 os << " - table = " << Brief(table());
879 JSObjectPrintBody(os, this);
880 }
881
882
883 template <class Derived, class TableType>
884 void
OrderedHashTableIteratorPrint(std::ostream & os)885 OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
886 std::ostream& os) { // NOLINT
887 os << "\n - table = " << Brief(table());
888 os << "\n - index = " << Brief(index());
889 os << "\n - kind = " << Brief(kind());
890 os << "\n";
891 }
892
893
894 template void OrderedHashTableIterator<
895 JSSetIterator,
896 OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
897
898
899 template void OrderedHashTableIterator<
900 JSMapIterator,
901 OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
902
903
JSSetIteratorPrint(std::ostream & os)904 void JSSetIterator::JSSetIteratorPrint(std::ostream& os) { // NOLINT
905 JSObjectPrintHeader(os, this, "JSSetIterator");
906 OrderedHashTableIteratorPrint(os);
907 }
908
909
JSMapIteratorPrint(std::ostream & os)910 void JSMapIterator::JSMapIteratorPrint(std::ostream& os) { // NOLINT
911 JSObjectPrintHeader(os, this, "JSMapIterator");
912 OrderedHashTableIteratorPrint(os);
913 }
914
915
JSWeakMapPrint(std::ostream & os)916 void JSWeakMap::JSWeakMapPrint(std::ostream& os) { // NOLINT
917 JSObjectPrintHeader(os, this, "JSWeakMap");
918 os << "\n - table = " << Brief(table());
919 JSObjectPrintBody(os, this);
920 }
921
922
JSWeakSetPrint(std::ostream & os)923 void JSWeakSet::JSWeakSetPrint(std::ostream& os) { // NOLINT
924 JSObjectPrintHeader(os, this, "JSWeakSet");
925 os << "\n - table = " << Brief(table());
926 JSObjectPrintBody(os, this);
927 }
928
929
JSArrayBufferPrint(std::ostream & os)930 void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) { // NOLINT
931 JSObjectPrintHeader(os, this, "JSArrayBuffer");
932 os << "\n - backing_store = " << backing_store();
933 os << "\n - byte_length = " << Brief(byte_length());
934 if (was_neutered()) os << "\n - neutered";
935 JSObjectPrintBody(os, this, !was_neutered());
936 }
937
938
JSTypedArrayPrint(std::ostream & os)939 void JSTypedArray::JSTypedArrayPrint(std::ostream& os) { // NOLINT
940 JSObjectPrintHeader(os, this, "JSTypedArray");
941 os << "\n - buffer = " << Brief(buffer());
942 os << "\n - byte_offset = " << Brief(byte_offset());
943 os << "\n - byte_length = " << Brief(byte_length());
944 os << "\n - length = " << Brief(length());
945 if (WasNeutered()) os << "\n - neutered";
946 JSObjectPrintBody(os, this, !WasNeutered());
947 }
948
JSArrayIteratorPrint(std::ostream & os)949 void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) { // NOLING
950 JSObjectPrintHeader(os, this, "JSArrayIterator");
951
952 InstanceType instance_type = map()->instance_type();
953 std::string type;
954 if (instance_type <= LAST_ARRAY_KEY_ITERATOR_TYPE) {
955 type = "keys";
956 } else if (instance_type <= LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE) {
957 type = "entries";
958 } else {
959 type = "values";
960 }
961
962 os << "\n - type = " << type;
963 os << "\n - object = " << Brief(object());
964 os << "\n - index = " << Brief(index());
965
966 JSObjectPrintBody(os, this);
967 }
968
JSDataViewPrint(std::ostream & os)969 void JSDataView::JSDataViewPrint(std::ostream& os) { // NOLINT
970 JSObjectPrintHeader(os, this, "JSDataView");
971 os << "\n - buffer =" << Brief(buffer());
972 os << "\n - byte_offset = " << Brief(byte_offset());
973 os << "\n - byte_length = " << Brief(byte_length());
974 if (WasNeutered()) os << "\n - neutered";
975 JSObjectPrintBody(os, this, !WasNeutered());
976 }
977
978
JSBoundFunctionPrint(std::ostream & os)979 void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT
980 JSObjectPrintHeader(os, this, "JSBoundFunction");
981 os << "\n - bound_target_function = " << Brief(bound_target_function());
982 os << "\n - bound_this = " << Brief(bound_this());
983 os << "\n - bound_arguments = " << Brief(bound_arguments());
984 JSObjectPrintBody(os, this);
985 }
986
987
JSFunctionPrint(std::ostream & os)988 void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT
989 JSObjectPrintHeader(os, this, "Function");
990 os << "\n - initial_map = ";
991 if (has_initial_map()) os << Brief(initial_map());
992 os << "\n - shared_info = " << Brief(shared());
993 os << "\n - name = " << Brief(shared()->name());
994 os << "\n - formal_parameter_count = "
995 << shared()->internal_formal_parameter_count();
996 if (IsGeneratorFunction(shared()->kind())) {
997 os << "\n - generator";
998 } else if (IsAsyncFunction(shared()->kind())) {
999 os << "\n - async";
1000 }
1001 os << "\n - context = " << Brief(context());
1002 os << "\n - feedback vector cell = " << Brief(feedback_vector_cell());
1003 os << "\n - code = " << Brief(code());
1004 JSObjectPrintBody(os, this);
1005 }
1006
1007 namespace {
1008
operator <<(std::ostream & os,FunctionKind kind)1009 std::ostream& operator<<(std::ostream& os, FunctionKind kind) {
1010 os << "[";
1011 if (kind == FunctionKind::kNormalFunction) {
1012 os << " NormalFunction";
1013 } else {
1014 #define PRINT_FLAG(name) \
1015 if (static_cast<int>(kind) & static_cast<int>(FunctionKind::k##name)) { \
1016 os << " " << #name; \
1017 }
1018
1019 PRINT_FLAG(ArrowFunction)
1020 PRINT_FLAG(GeneratorFunction)
1021 PRINT_FLAG(ConciseMethod)
1022 PRINT_FLAG(DefaultConstructor)
1023 PRINT_FLAG(DerivedConstructor)
1024 PRINT_FLAG(BaseConstructor)
1025 PRINT_FLAG(GetterFunction)
1026 PRINT_FLAG(SetterFunction)
1027 PRINT_FLAG(AsyncFunction)
1028 PRINT_FLAG(Module)
1029 #undef PRINT_FLAG
1030 }
1031 return os << " ]";
1032 }
1033
1034 } // namespace
1035
SharedFunctionInfoPrint(std::ostream & os)1036 void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) { // NOLINT
1037 HeapObject::PrintHeader(os, "SharedFunctionInfo");
1038 os << "\n - name = " << Brief(name());
1039 os << "\n - kind = " << kind();
1040 os << "\n - formal_parameter_count = " << internal_formal_parameter_count();
1041 os << "\n - expected_nof_properties = " << expected_nof_properties();
1042 os << "\n - language_mode = " << language_mode();
1043 os << "\n - ast_node_count = " << ast_node_count();
1044 os << "\n - instance class name = ";
1045 instance_class_name()->Print(os);
1046 os << "\n - code = " << Brief(code());
1047 if (HasSourceCode()) {
1048 os << "\n - source code = ";
1049 String* source = String::cast(Script::cast(script())->source());
1050 int start = start_position();
1051 int length = end_position() - start;
1052 std::unique_ptr<char[]> source_string = source->ToCString(
1053 DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL);
1054 os << source_string.get();
1055 }
1056 // Script files are often large, hard to read.
1057 // os << "\n - script =";
1058 // script()->Print(os);
1059 if (is_named_expression()) {
1060 os << "\n - named expression";
1061 } else if (is_anonymous_expression()) {
1062 os << "\n - anonymous expression";
1063 } else if (is_declaration()) {
1064 os << "\n - declaration";
1065 }
1066 os << "\n - function token position = " << function_token_position();
1067 os << "\n - start position = " << start_position();
1068 os << "\n - end position = " << end_position();
1069 if (HasDebugInfo()) {
1070 os << "\n - debug info = " << Brief(debug_info());
1071 } else {
1072 os << "\n - no debug info";
1073 }
1074 os << "\n - length = " << length();
1075 os << "\n - optimized_code_map = " << Brief(optimized_code_map());
1076 os << "\n - feedback_metadata = ";
1077 feedback_metadata()->FeedbackMetadataPrint(os);
1078 if (HasBytecodeArray()) {
1079 os << "\n - bytecode_array = " << bytecode_array();
1080 }
1081 os << "\n";
1082 }
1083
1084
JSGlobalProxyPrint(std::ostream & os)1085 void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) { // NOLINT
1086 JSObjectPrintHeader(os, this, "JSGlobalProxy");
1087 if (!GetIsolate()->bootstrapper()->IsActive()) {
1088 os << "\n - native context = " << Brief(native_context());
1089 }
1090 os << "\n - hash = " << Brief(hash());
1091 JSObjectPrintBody(os, this);
1092 }
1093
1094
JSGlobalObjectPrint(std::ostream & os)1095 void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) { // NOLINT
1096 JSObjectPrintHeader(os, this, "JSGlobalObject");
1097 if (!GetIsolate()->bootstrapper()->IsActive()) {
1098 os << "\n - native context = " << Brief(native_context());
1099 }
1100 os << "\n - global proxy = " << Brief(global_proxy());
1101 JSObjectPrintBody(os, this);
1102 }
1103
1104
CellPrint(std::ostream & os)1105 void Cell::CellPrint(std::ostream& os) { // NOLINT
1106 HeapObject::PrintHeader(os, "Cell");
1107 os << "\n - value: " << Brief(value());
1108 os << "\n";
1109 }
1110
1111
PropertyCellPrint(std::ostream & os)1112 void PropertyCell::PropertyCellPrint(std::ostream& os) { // NOLINT
1113 HeapObject::PrintHeader(os, "PropertyCell");
1114 os << "\n - value: " << Brief(value());
1115 os << "\n - details: ";
1116 property_details().PrintAsSlowTo(os);
1117 PropertyCellType cell_type = property_details().cell_type();
1118 os << "\n - cell_type: ";
1119 if (value()->IsTheHole(GetIsolate())) {
1120 switch (cell_type) {
1121 case PropertyCellType::kUninitialized:
1122 os << "Uninitialized";
1123 break;
1124 case PropertyCellType::kInvalidated:
1125 os << "Invalidated";
1126 break;
1127 default:
1128 os << "??? " << static_cast<int>(cell_type);
1129 break;
1130 }
1131 } else {
1132 switch (cell_type) {
1133 case PropertyCellType::kUndefined:
1134 os << "Undefined";
1135 break;
1136 case PropertyCellType::kConstant:
1137 os << "Constant";
1138 break;
1139 case PropertyCellType::kConstantType:
1140 os << "ConstantType"
1141 << " (";
1142 switch (GetConstantType()) {
1143 case PropertyCellConstantType::kSmi:
1144 os << "Smi";
1145 break;
1146 case PropertyCellConstantType::kStableMap:
1147 os << "StableMap";
1148 break;
1149 }
1150 os << ")";
1151 break;
1152 case PropertyCellType::kMutable:
1153 os << "Mutable";
1154 break;
1155 }
1156 }
1157 os << "\n";
1158 }
1159
1160
WeakCellPrint(std::ostream & os)1161 void WeakCell::WeakCellPrint(std::ostream& os) { // NOLINT
1162 HeapObject::PrintHeader(os, "WeakCell");
1163 if (cleared()) {
1164 os << "\n - cleared";
1165 } else {
1166 os << "\n - value: " << Brief(value());
1167 }
1168 os << "\n";
1169 }
1170
1171
CodePrint(std::ostream & os)1172 void Code::CodePrint(std::ostream& os) { // NOLINT
1173 HeapObject::PrintHeader(os, "Code");
1174 os << "\n";
1175 #ifdef ENABLE_DISASSEMBLER
1176 if (FLAG_use_verbose_printer) {
1177 Disassemble(NULL, os);
1178 }
1179 #endif
1180 }
1181
1182
ForeignPrint(std::ostream & os)1183 void Foreign::ForeignPrint(std::ostream& os) { // NOLINT
1184 os << "foreign address : " << foreign_address();
1185 os << "\n";
1186 }
1187
1188
AccessorInfoPrint(std::ostream & os)1189 void AccessorInfo::AccessorInfoPrint(std::ostream& os) { // NOLINT
1190 HeapObject::PrintHeader(os, "AccessorInfo");
1191 os << "\n - name: " << Brief(name());
1192 os << "\n - flag: " << flag();
1193 os << "\n - getter: " << Brief(getter());
1194 os << "\n - setter: " << Brief(setter());
1195 os << "\n - js_getter: " << Brief(js_getter());
1196 os << "\n - data: " << Brief(data());
1197 os << "\n";
1198 }
1199
1200
PromiseResolveThenableJobInfoPrint(std::ostream & os)1201 void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoPrint(
1202 std::ostream& os) { // NOLINT
1203 HeapObject::PrintHeader(os, "PromiseResolveThenableJobInfo");
1204 os << "\n - thenable: " << Brief(thenable());
1205 os << "\n - then: " << Brief(then());
1206 os << "\n - resolve: " << Brief(resolve());
1207 os << "\n - reject: " << Brief(reject());
1208 os << "\n - context: " << Brief(context());
1209 os << "\n";
1210 }
1211
PromiseReactionJobInfoPrint(std::ostream & os)1212 void PromiseReactionJobInfo::PromiseReactionJobInfoPrint(
1213 std::ostream& os) { // NOLINT
1214 HeapObject::PrintHeader(os, "PromiseReactionJobInfo");
1215 os << "\n - value: " << Brief(value());
1216 os << "\n - tasks: " << Brief(tasks());
1217 os << "\n - deferred_promise: " << Brief(deferred_promise());
1218 os << "\n - deferred_on_resolve: " << Brief(deferred_on_resolve());
1219 os << "\n - deferred_on_reject: " << Brief(deferred_on_reject());
1220 os << "\n - reaction context: " << Brief(context());
1221 os << "\n";
1222 }
1223
ModuleInfoEntryPrint(std::ostream & os)1224 void ModuleInfoEntry::ModuleInfoEntryPrint(std::ostream& os) { // NOLINT
1225 HeapObject::PrintHeader(os, "ModuleInfoEntry");
1226 os << "\n - export_name: " << Brief(export_name());
1227 os << "\n - local_name: " << Brief(local_name());
1228 os << "\n - import_name: " << Brief(import_name());
1229 os << "\n - module_request: " << module_request();
1230 os << "\n - cell_index: " << cell_index();
1231 os << "\n - beg_pos: " << beg_pos();
1232 os << "\n - end_pos: " << end_pos();
1233 os << "\n";
1234 }
1235
ModulePrint(std::ostream & os)1236 void Module::ModulePrint(std::ostream& os) { // NOLINT
1237 HeapObject::PrintHeader(os, "Module");
1238 // TODO(neis): Simplify once modules have a script field.
1239 if (!evaluated()) {
1240 SharedFunctionInfo* shared = code()->IsSharedFunctionInfo()
1241 ? SharedFunctionInfo::cast(code())
1242 : JSFunction::cast(code())->shared();
1243 Object* origin = Script::cast(shared->script())->GetNameOrSourceURL();
1244 os << "\n - origin: " << Brief(origin);
1245 }
1246 os << "\n - code: " << Brief(code());
1247 os << "\n - exports: " << Brief(exports());
1248 os << "\n - requested_modules: " << Brief(requested_modules());
1249 os << "\n - instantiated, evaluated: " << instantiated() << ", "
1250 << evaluated();
1251 os << "\n";
1252 }
1253
JSModuleNamespacePrint(std::ostream & os)1254 void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) { // NOLINT
1255 JSObjectPrintHeader(os, this, "JSModuleNamespace");
1256 os << "\n - module: " << Brief(module());
1257 JSObjectPrintBody(os, this);
1258 }
1259
PrototypeInfoPrint(std::ostream & os)1260 void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT
1261 HeapObject::PrintHeader(os, "PrototypeInfo");
1262 os << "\n - weak cell: " << Brief(weak_cell());
1263 os << "\n - prototype users: " << Brief(prototype_users());
1264 os << "\n - registry slot: " << registry_slot();
1265 os << "\n - validity cell: " << Brief(validity_cell());
1266 os << "\n - object create map: " << Brief(object_create_map());
1267 os << "\n";
1268 }
1269
Tuple2Print(std::ostream & os)1270 void Tuple2::Tuple2Print(std::ostream& os) { // NOLINT
1271 HeapObject::PrintHeader(os, "Tuple2");
1272 os << "\n - value1: " << Brief(value1());
1273 os << "\n - value2: " << Brief(value2());
1274 os << "\n";
1275 }
1276
Tuple3Print(std::ostream & os)1277 void Tuple3::Tuple3Print(std::ostream& os) { // NOLINT
1278 HeapObject::PrintHeader(os, "Tuple3");
1279 os << "\n - value1: " << Brief(value1());
1280 os << "\n - value2: " << Brief(value2());
1281 os << "\n - value3: " << Brief(value3());
1282 os << "\n";
1283 }
1284
ContextExtensionPrint(std::ostream & os)1285 void ContextExtension::ContextExtensionPrint(std::ostream& os) { // NOLINT
1286 HeapObject::PrintHeader(os, "ContextExtension");
1287 os << "\n - scope_info: " << Brief(scope_info());
1288 os << "\n - extension: " << Brief(extension());
1289 os << "\n";
1290 }
1291
ConstantElementsPairPrint(std::ostream & os)1292 void ConstantElementsPair::ConstantElementsPairPrint(
1293 std::ostream& os) { // NOLINT
1294 HeapObject::PrintHeader(os, "ConstantElementsPair");
1295 os << "\n - elements_kind: " << static_cast<ElementsKind>(elements_kind());
1296 os << "\n - constant_values: " << Brief(constant_values());
1297 os << "\n";
1298 }
1299
AccessorPairPrint(std::ostream & os)1300 void AccessorPair::AccessorPairPrint(std::ostream& os) { // NOLINT
1301 HeapObject::PrintHeader(os, "AccessorPair");
1302 os << "\n - getter: " << Brief(getter());
1303 os << "\n - setter: " << Brief(setter());
1304 os << "\n";
1305 }
1306
1307
AccessCheckInfoPrint(std::ostream & os)1308 void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) { // NOLINT
1309 HeapObject::PrintHeader(os, "AccessCheckInfo");
1310 os << "\n - callback: " << Brief(callback());
1311 os << "\n - named_interceptor: " << Brief(named_interceptor());
1312 os << "\n - indexed_interceptor: " << Brief(indexed_interceptor());
1313 os << "\n - data: " << Brief(data());
1314 os << "\n";
1315 }
1316
1317
InterceptorInfoPrint(std::ostream & os)1318 void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) { // NOLINT
1319 HeapObject::PrintHeader(os, "InterceptorInfo");
1320 os << "\n - getter: " << Brief(getter());
1321 os << "\n - setter: " << Brief(setter());
1322 os << "\n - query: " << Brief(query());
1323 os << "\n - deleter: " << Brief(deleter());
1324 os << "\n - enumerator: " << Brief(enumerator());
1325 os << "\n - data: " << Brief(data());
1326 os << "\n";
1327 }
1328
1329
CallHandlerInfoPrint(std::ostream & os)1330 void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) { // NOLINT
1331 HeapObject::PrintHeader(os, "CallHandlerInfo");
1332 os << "\n - callback: " << Brief(callback());
1333 os << "\n - data: " << Brief(data());
1334 os << "\n";
1335 }
1336
1337
FunctionTemplateInfoPrint(std::ostream & os)1338 void FunctionTemplateInfo::FunctionTemplateInfoPrint(
1339 std::ostream& os) { // NOLINT
1340 HeapObject::PrintHeader(os, "FunctionTemplateInfo");
1341 os << "\n - class name: " << Brief(class_name());
1342 os << "\n - tag: " << Brief(tag());
1343 os << "\n - serial_number: " << Brief(serial_number());
1344 os << "\n - property_list: " << Brief(property_list());
1345 os << "\n - call_code: " << Brief(call_code());
1346 os << "\n - property_accessors: " << Brief(property_accessors());
1347 os << "\n - prototype_template: " << Brief(prototype_template());
1348 os << "\n - parent_template: " << Brief(parent_template());
1349 os << "\n - named_property_handler: " << Brief(named_property_handler());
1350 os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
1351 os << "\n - instance_template: " << Brief(instance_template());
1352 os << "\n - signature: " << Brief(signature());
1353 os << "\n - access_check_info: " << Brief(access_check_info());
1354 os << "\n - cached_property_name: " << Brief(cached_property_name());
1355 os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
1356 os << "\n - undetectable: " << (undetectable() ? "true" : "false");
1357 os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1358 os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1359 os << "\n";
1360 }
1361
1362
ObjectTemplateInfoPrint(std::ostream & os)1363 void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) { // NOLINT
1364 HeapObject::PrintHeader(os, "ObjectTemplateInfo");
1365 os << "\n - tag: " << Brief(tag());
1366 os << "\n - serial_number: " << Brief(serial_number());
1367 os << "\n - property_list: " << Brief(property_list());
1368 os << "\n - property_accessors: " << Brief(property_accessors());
1369 os << "\n - constructor: " << Brief(constructor());
1370 os << "\n - internal_field_count: " << internal_field_count();
1371 os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false");
1372 os << "\n";
1373 }
1374
1375
AllocationSitePrint(std::ostream & os)1376 void AllocationSite::AllocationSitePrint(std::ostream& os) { // NOLINT
1377 HeapObject::PrintHeader(os, "AllocationSite");
1378 os << "\n - weak_next: " << Brief(weak_next());
1379 os << "\n - dependent code: " << Brief(dependent_code());
1380 os << "\n - nested site: " << Brief(nested_site());
1381 os << "\n - memento found count: "
1382 << Brief(Smi::FromInt(memento_found_count()));
1383 os << "\n - memento create count: "
1384 << Brief(Smi::FromInt(memento_create_count()));
1385 os << "\n - pretenure decision: "
1386 << Brief(Smi::FromInt(pretenure_decision()));
1387 os << "\n - transition_info: ";
1388 if (transition_info()->IsSmi()) {
1389 ElementsKind kind = GetElementsKind();
1390 os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1391 } else if (transition_info()->IsJSArray()) {
1392 os << "Array literal " << Brief(transition_info());
1393 } else {
1394 os << "unknown transition_info " << Brief(transition_info());
1395 }
1396 os << "\n";
1397 }
1398
1399
AllocationMementoPrint(std::ostream & os)1400 void AllocationMemento::AllocationMementoPrint(std::ostream& os) { // NOLINT
1401 HeapObject::PrintHeader(os, "AllocationMemento");
1402 os << "\n - allocation site: ";
1403 if (IsValid()) {
1404 GetAllocationSite()->Print(os);
1405 } else {
1406 os << "<invalid>\n";
1407 }
1408 }
1409
1410
ScriptPrint(std::ostream & os)1411 void Script::ScriptPrint(std::ostream& os) { // NOLINT
1412 HeapObject::PrintHeader(os, "Script");
1413 os << "\n - source: " << Brief(source());
1414 os << "\n - name: " << Brief(name());
1415 os << "\n - line_offset: " << line_offset();
1416 os << "\n - column_offset: " << column_offset();
1417 os << "\n - type: " << type();
1418 os << "\n - id: " << id();
1419 os << "\n - context data: " << Brief(context_data());
1420 os << "\n - wrapper: " << Brief(wrapper());
1421 os << "\n - compilation type: " << compilation_type();
1422 os << "\n - line ends: " << Brief(line_ends());
1423 os << "\n - eval from shared: " << Brief(eval_from_shared());
1424 os << "\n - eval from position: " << eval_from_position();
1425 os << "\n - shared function infos: " << Brief(shared_function_infos());
1426 os << "\n";
1427 }
1428
1429
DebugInfoPrint(std::ostream & os)1430 void DebugInfo::DebugInfoPrint(std::ostream& os) { // NOLINT
1431 HeapObject::PrintHeader(os, "DebugInfo");
1432 os << "\n - shared: " << Brief(shared());
1433 os << "\n - debug bytecode array: " << Brief(debug_bytecode_array());
1434 os << "\n - break_points: ";
1435 break_points()->Print(os);
1436 }
1437
1438
BreakPointInfoPrint(std::ostream & os)1439 void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT
1440 HeapObject::PrintHeader(os, "BreakPointInfo");
1441 os << "\n - source_position: " << source_position();
1442 os << "\n - break_point_objects: " << Brief(break_point_objects());
1443 os << "\n";
1444 }
1445
1446
PrintBitMask(std::ostream & os,uint32_t value)1447 static void PrintBitMask(std::ostream& os, uint32_t value) { // NOLINT
1448 for (int i = 0; i < 32; i++) {
1449 if ((i & 7) == 0) os << " ";
1450 os << (((value & 1) == 0) ? "_" : "x");
1451 value >>= 1;
1452 }
1453 }
1454
1455
Print()1456 void LayoutDescriptor::Print() {
1457 OFStream os(stdout);
1458 this->Print(os);
1459 os << std::flush;
1460 }
1461
ShortPrint(std::ostream & os)1462 void LayoutDescriptor::ShortPrint(std::ostream& os) {
1463 if (IsSmi()) {
1464 os << this; // Print tagged value for easy use with "jld" gdb macro.
1465 } else {
1466 os << Brief(this);
1467 }
1468 }
1469
Print(std::ostream & os)1470 void LayoutDescriptor::Print(std::ostream& os) { // NOLINT
1471 os << "Layout descriptor: ";
1472 if (IsFastPointerLayout()) {
1473 os << "<all tagged>";
1474 } else if (IsSmi()) {
1475 os << "fast";
1476 PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
1477 } else if (IsOddball() &&
1478 IsUninitialized(HeapObject::cast(this)->GetIsolate())) {
1479 os << "<uninitialized>";
1480 } else {
1481 os << "slow";
1482 int len = length();
1483 for (int i = 0; i < len; i++) {
1484 if (i > 0) os << " |";
1485 PrintBitMask(os, get_scalar(i));
1486 }
1487 }
1488 os << "\n";
1489 }
1490
1491
1492 #endif // OBJECT_PRINT
1493
1494
1495 #if TRACE_MAPS
1496
1497
NameShortPrint()1498 void Name::NameShortPrint() {
1499 if (this->IsString()) {
1500 PrintF("%s", String::cast(this)->ToCString().get());
1501 } else {
1502 DCHECK(this->IsSymbol());
1503 Symbol* s = Symbol::cast(this);
1504 if (s->name()->IsUndefined(GetIsolate())) {
1505 PrintF("#<%s>", s->PrivateSymbolToName());
1506 } else {
1507 PrintF("<%s>", String::cast(s->name())->ToCString().get());
1508 }
1509 }
1510 }
1511
1512
NameShortPrint(Vector<char> str)1513 int Name::NameShortPrint(Vector<char> str) {
1514 if (this->IsString()) {
1515 return SNPrintF(str, "%s", String::cast(this)->ToCString().get());
1516 } else {
1517 DCHECK(this->IsSymbol());
1518 Symbol* s = Symbol::cast(this);
1519 if (s->name()->IsUndefined(GetIsolate())) {
1520 return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
1521 } else {
1522 return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
1523 }
1524 }
1525 }
1526
1527
1528 #endif // TRACE_MAPS
1529
1530
1531 #if defined(DEBUG) || defined(OBJECT_PRINT)
1532 // This method is only meant to be called from gdb for debugging purposes.
1533 // Since the string can also be in two-byte encoding, non-Latin1 characters
1534 // will be ignored in the output.
ToAsciiArray()1535 char* String::ToAsciiArray() {
1536 // Static so that subsequent calls frees previously allocated space.
1537 // This also means that previous results will be overwritten.
1538 static char* buffer = NULL;
1539 if (buffer != NULL) delete[] buffer;
1540 buffer = new char[length() + 1];
1541 WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
1542 buffer[length()] = 0;
1543 return buffer;
1544 }
1545
1546
Print()1547 void DescriptorArray::Print() {
1548 OFStream os(stdout);
1549 this->PrintDescriptors(os);
1550 os << std::flush;
1551 }
1552
1553
PrintDescriptors(std::ostream & os)1554 void DescriptorArray::PrintDescriptors(std::ostream& os) { // NOLINT
1555 HandleScope scope(GetIsolate());
1556 os << "Descriptor array #" << number_of_descriptors() << ":";
1557 for (int i = 0; i < number_of_descriptors(); i++) {
1558 Name* key = GetKey(i);
1559 os << "\n [" << i << "]: ";
1560 #ifdef OBJECT_PRINT
1561 key->NamePrint(os);
1562 #else
1563 key->ShortPrint(os);
1564 #endif
1565 os << " ";
1566 PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull);
1567 }
1568 os << "\n";
1569 }
1570
PrintDescriptorDetails(std::ostream & os,int descriptor,PropertyDetails::PrintMode mode)1571 void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor,
1572 PropertyDetails::PrintMode mode) {
1573 PropertyDetails details = GetDetails(descriptor);
1574 details.PrintAsFastTo(os, mode);
1575 os << " @ ";
1576 Object* value = GetValue(descriptor);
1577 switch (details.location()) {
1578 case kField: {
1579 FieldType* field_type = Map::UnwrapFieldType(value);
1580 field_type->PrintTo(os);
1581 break;
1582 }
1583 case kDescriptor:
1584 os << Brief(value);
1585 if (value->IsAccessorPair()) {
1586 AccessorPair* pair = AccessorPair::cast(value);
1587 os << "(get: " << Brief(pair->getter())
1588 << ", set: " << Brief(pair->setter()) << ")";
1589 }
1590 break;
1591 }
1592 }
1593
Print()1594 void TransitionArray::Print() {
1595 OFStream os(stdout);
1596 TransitionArray::PrintTransitions(os, this);
1597 os << "\n" << std::flush;
1598 }
1599
1600
PrintTransitions(std::ostream & os,Object * transitions,bool print_header)1601 void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions,
1602 bool print_header) { // NOLINT
1603 int num_transitions = NumberOfTransitions(transitions);
1604 if (print_header) {
1605 os << "Transition array #" << num_transitions << ":";
1606 }
1607 for (int i = 0; i < num_transitions; i++) {
1608 Name* key = GetKey(transitions, i);
1609 Map* target = GetTarget(transitions, i);
1610 os << "\n ";
1611 #ifdef OBJECT_PRINT
1612 key->NamePrint(os);
1613 #else
1614 key->ShortPrint(os);
1615 #endif
1616 os << ": ";
1617 Heap* heap = key->GetHeap();
1618 if (key == heap->nonextensible_symbol()) {
1619 os << "(transition to non-extensible)";
1620 } else if (key == heap->sealed_symbol()) {
1621 os << "(transition to sealed)";
1622 } else if (key == heap->frozen_symbol()) {
1623 os << "(transition to frozen)";
1624 } else if (key == heap->elements_transition_symbol()) {
1625 os << "(transition to " << ElementsKindToString(target->elements_kind())
1626 << ")";
1627 } else if (key == heap->strict_function_transition_symbol()) {
1628 os << " (transition to strict function)";
1629 } else {
1630 DCHECK(!IsSpecialTransition(key));
1631 os << "(transition to ";
1632 int descriptor = target->LastAdded();
1633 DescriptorArray* descriptors = target->instance_descriptors();
1634 descriptors->PrintDescriptorDetails(os, descriptor,
1635 PropertyDetails::kForTransitions);
1636 os << ")";
1637 }
1638 os << " -> " << Brief(target);
1639 }
1640 }
1641
1642
PrintTransitions(std::ostream & os)1643 void JSObject::PrintTransitions(std::ostream& os) { // NOLINT
1644 Object* transitions = map()->raw_transitions();
1645 int num_transitions = TransitionArray::NumberOfTransitions(transitions);
1646 if (num_transitions == 0) return;
1647 os << "\n - transitions";
1648 TransitionArray::PrintTransitions(os, transitions, false);
1649 }
1650 #endif // defined(DEBUG) || defined(OBJECT_PRINT)
1651 } // namespace internal
1652 } // namespace v8
1653
1654 //
1655 // The following functions are used by our gdb macros.
1656 //
_v8_internal_Print_Object(void * object)1657 extern void _v8_internal_Print_Object(void* object) {
1658 reinterpret_cast<i::Object*>(object)->Print();
1659 }
1660
_v8_internal_Print_Code(void * object)1661 extern void _v8_internal_Print_Code(void* object) {
1662 i::Isolate* isolate = i::Isolate::Current();
1663 isolate->FindCodeObject(reinterpret_cast<i::Address>(object))->Print();
1664 }
1665
_v8_internal_Print_FeedbackMetadata(void * object)1666 extern void _v8_internal_Print_FeedbackMetadata(void* object) {
1667 if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
1668 printf("Not a feedback metadata object\n");
1669 } else {
1670 reinterpret_cast<i::FeedbackMetadata*>(object)->Print();
1671 }
1672 }
1673
_v8_internal_Print_FeedbackVector(void * object)1674 extern void _v8_internal_Print_FeedbackVector(void* object) {
1675 if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
1676 printf("Not a feedback vector\n");
1677 } else {
1678 reinterpret_cast<i::FeedbackVector*>(object)->Print();
1679 }
1680 }
1681
_v8_internal_Print_DescriptorArray(void * object)1682 extern void _v8_internal_Print_DescriptorArray(void* object) {
1683 if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
1684 printf("Not a descriptor array\n");
1685 } else {
1686 reinterpret_cast<i::DescriptorArray*>(object)->Print();
1687 }
1688 }
1689
_v8_internal_Print_LayoutDescriptor(void * object)1690 extern void _v8_internal_Print_LayoutDescriptor(void* object) {
1691 i::Object* o = reinterpret_cast<i::Object*>(object);
1692 if (!o->IsLayoutDescriptor()) {
1693 printf("Not a layout descriptor\n");
1694 } else {
1695 reinterpret_cast<i::LayoutDescriptor*>(object)->Print();
1696 }
1697 }
1698
_v8_internal_Print_TransitionArray(void * object)1699 extern void _v8_internal_Print_TransitionArray(void* object) {
1700 if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
1701 printf("Not a transition array\n");
1702 } else {
1703 reinterpret_cast<i::TransitionArray*>(object)->Print();
1704 }
1705 }
1706
_v8_internal_Print_StackTrace()1707 extern void _v8_internal_Print_StackTrace() {
1708 i::Isolate* isolate = i::Isolate::Current();
1709 isolate->PrintStack(stdout);
1710 }
1711