blob: 1c1ffed811c72cbaa65f46aa566b5392e8f0a06f [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "disassembler.h"
31#include "disasm.h"
32#include "macro-assembler.h"
33
34namespace v8 { namespace internal {
35
36#ifdef DEBUG
37
38static const char* TypeToString(InstanceType type);
39
40
41void Object::Print() {
42 if (IsSmi()) {
43 Smi::cast(this)->SmiPrint();
44 } else if (IsFailure()) {
45 Failure::cast(this)->FailurePrint();
46 } else {
47 HeapObject::cast(this)->HeapObjectPrint();
48 }
49 Flush();
50}
51
52
53void Object::PrintLn() {
54 Print();
55 PrintF("\n");
56}
57
58
59void Object::Verify() {
60 if (IsSmi()) {
61 Smi::cast(this)->SmiVerify();
62 } else if (IsFailure()) {
63 Failure::cast(this)->FailureVerify();
64 } else {
65 HeapObject::cast(this)->HeapObjectVerify();
66 }
67}
68
69
70void Object::VerifyPointer(Object* p) {
71 if (p->IsHeapObject()) {
72 HeapObject::VerifyHeapPointer(p);
73 } else {
74 ASSERT(p->IsSmi());
75 }
76}
77
78
79void Smi::SmiVerify() {
80 ASSERT(IsSmi());
81}
82
83
84void Failure::FailureVerify() {
85 ASSERT(IsFailure());
86}
87
88
89void HeapObject::PrintHeader(const char* id) {
90 PrintF("%p: [%s]\n", this, id);
91}
92
93
94void HeapObject::HeapObjectPrint() {
95 InstanceType instance_type = map()->instance_type();
96
97 HandleScope scope;
98 if (instance_type < FIRST_NONSTRING_TYPE) {
99 String::cast(this)->StringPrint();
100 return;
101 }
102
103 switch (instance_type) {
104 case MAP_TYPE:
105 Map::cast(this)->MapPrint();
106 break;
107 case HEAP_NUMBER_TYPE:
108 HeapNumber::cast(this)->HeapNumberPrint();
109 break;
110 case FIXED_ARRAY_TYPE:
111 FixedArray::cast(this)->FixedArrayPrint();
112 break;
113 case BYTE_ARRAY_TYPE:
114 ByteArray::cast(this)->ByteArrayPrint();
115 break;
116 case FILLER_TYPE:
117 PrintF("filler");
118 break;
119 case JS_OBJECT_TYPE: // fall through
120 case JS_ARRAY_TYPE:
ager@chromium.org236ad962008-09-25 09:45:57 +0000121 case JS_REGEXP_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000122 JSObject::cast(this)->JSObjectPrint();
123 break;
124 case ODDBALL_TYPE:
125 Oddball::cast(this)->to_string()->Print();
126 break;
127 case JS_FUNCTION_TYPE:
128 JSFunction::cast(this)->JSFunctionPrint();
129 break;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000130 case JS_GLOBAL_PROXY_TYPE:
131 JSGlobalProxy::cast(this)->JSGlobalProxyPrint();
132 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000133 case JS_GLOBAL_OBJECT_TYPE:
134 JSGlobalObject::cast(this)->JSGlobalObjectPrint();
135 break;
136 case JS_BUILTINS_OBJECT_TYPE:
137 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
138 break;
139 case JS_VALUE_TYPE:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000140 PrintF("Value wrapper around:");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000141 JSValue::cast(this)->value()->Print();
142 break;
143 case CODE_TYPE:
144 Code::cast(this)->CodePrint();
145 break;
146 case PROXY_TYPE:
147 Proxy::cast(this)->ProxyPrint();
148 break;
149 case SHARED_FUNCTION_INFO_TYPE:
150 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint();
151 break;
152
153#define MAKE_STRUCT_CASE(NAME, Name, name) \
154 case NAME##_TYPE: \
155 Name::cast(this)->Name##Print(); \
156 break;
157 STRUCT_LIST(MAKE_STRUCT_CASE)
158#undef MAKE_STRUCT_CASE
159
160 default:
161 PrintF("UNKNOWN TYPE %d", map()->instance_type());
162 UNREACHABLE();
163 break;
164 }
165}
166
167
168void HeapObject::HeapObjectVerify() {
169 InstanceType instance_type = map()->instance_type();
170
171 if (instance_type < FIRST_NONSTRING_TYPE) {
172 String::cast(this)->StringVerify();
173 return;
174 }
175
176 switch (instance_type) {
177 case MAP_TYPE:
178 Map::cast(this)->MapVerify();
179 break;
180 case HEAP_NUMBER_TYPE:
181 HeapNumber::cast(this)->HeapNumberVerify();
182 break;
183 case FIXED_ARRAY_TYPE:
184 FixedArray::cast(this)->FixedArrayVerify();
185 break;
186 case BYTE_ARRAY_TYPE:
187 ByteArray::cast(this)->ByteArrayVerify();
188 break;
189 case CODE_TYPE:
190 Code::cast(this)->CodeVerify();
191 break;
192 case ODDBALL_TYPE:
193 Oddball::cast(this)->OddballVerify();
194 break;
195 case JS_OBJECT_TYPE:
196 JSObject::cast(this)->JSObjectVerify();
197 break;
198 case JS_VALUE_TYPE:
199 JSValue::cast(this)->JSValueVerify();
200 break;
201 case JS_FUNCTION_TYPE:
202 JSFunction::cast(this)->JSFunctionVerify();
203 break;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000204 case JS_GLOBAL_PROXY_TYPE:
205 JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
206 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000207 case JS_GLOBAL_OBJECT_TYPE:
208 JSGlobalObject::cast(this)->JSGlobalObjectVerify();
209 break;
210 case JS_BUILTINS_OBJECT_TYPE:
211 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
212 break;
213 case JS_ARRAY_TYPE:
214 JSArray::cast(this)->JSArrayVerify();
215 break;
ager@chromium.org236ad962008-09-25 09:45:57 +0000216 case JS_REGEXP_TYPE:
217 JSRegExp::cast(this)->JSRegExpVerify();
218 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000219 case FILLER_TYPE:
220 break;
221 case PROXY_TYPE:
222 Proxy::cast(this)->ProxyVerify();
223 break;
224 case SHARED_FUNCTION_INFO_TYPE:
225 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
226 break;
227
228#define MAKE_STRUCT_CASE(NAME, Name, name) \
229 case NAME##_TYPE: \
230 Name::cast(this)->Name##Verify(); \
231 break;
232 STRUCT_LIST(MAKE_STRUCT_CASE)
233#undef MAKE_STRUCT_CASE
234
235 default:
236 UNREACHABLE();
237 break;
238 }
239}
240
241
242void HeapObject::VerifyHeapPointer(Object* p) {
243 ASSERT(p->IsHeapObject());
244 ASSERT(Heap::Contains(HeapObject::cast(p)));
245}
246
247
248void HeapNumber::HeapNumberVerify() {
249 ASSERT(IsHeapNumber());
250}
251
252
253void ByteArray::ByteArrayPrint() {
254 PrintF("byte array, data starts at %p", GetDataStartAddress());
255}
256
257
258void ByteArray::ByteArrayVerify() {
259 ASSERT(IsByteArray());
260}
261
262
263void JSObject::PrintProperties() {
264 if (HasFastProperties()) {
265 for (DescriptorReader r(map()->instance_descriptors());
266 !r.eos();
267 r.advance()) {
268 PrintF(" ");
269 r.GetKey()->StringPrint();
270 PrintF(": ");
271 if (r.type() == FIELD) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000272 FastPropertyAt(r.GetFieldIndex())->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000273 PrintF(" (field at offset %d)\n", r.GetFieldIndex());
274 } else if (r.type() == CONSTANT_FUNCTION) {
275 r.GetConstantFunction()->ShortPrint();
276 PrintF(" (constant function)\n");
277 } else if (r.type() == CALLBACKS) {
278 r.GetCallbacksObject()->ShortPrint();
279 PrintF(" (callback)\n");
280 } else if (r.type() == MAP_TRANSITION) {
281 PrintF(" (map transition)\n");
282 } else {
283 UNREACHABLE();
284 }
285 }
286 } else {
287 property_dictionary()->Print();
288 }
289}
290
291
292void JSObject::PrintElements() {
293 if (HasFastElements()) {
294 FixedArray* p = FixedArray::cast(elements());
295 for (int i = 0; i < p->length(); i++) {
296 PrintF(" %d: ", i);
297 p->get(i)->ShortPrint();
298 PrintF("\n");
299 }
300 } else {
301 elements()->Print();
302 }
303}
304
305
306void JSObject::JSObjectPrint() {
307 PrintF("%p: [JSObject]\n", this);
308 PrintF(" - map = %p\n", map());
309 PrintF(" - prototype = %p\n", GetPrototype());
310 PrintF(" {\n");
311 PrintProperties();
312 PrintElements();
313 PrintF(" }\n");
314}
315
316
317void JSObject::JSObjectVerify() {
318 VerifyHeapPointer(properties());
319 VerifyHeapPointer(elements());
320 if (HasFastProperties()) {
321 CHECK(map()->unused_property_fields() ==
ager@chromium.org7c537e22008-10-16 08:43:32 +0000322 (map()->inobject_properties() + properties()->length() -
323 map()->NextFreePropertyIndex()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000324 }
325}
326
327
328static const char* TypeToString(InstanceType type) {
329 switch (type) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000330 case INVALID_TYPE: return "INVALID";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000331 case MAP_TYPE: return "MAP";
332 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
333 case SHORT_SYMBOL_TYPE:
334 case MEDIUM_SYMBOL_TYPE:
335 case LONG_SYMBOL_TYPE: return "SYMBOL";
336 case SHORT_ASCII_SYMBOL_TYPE:
337 case MEDIUM_ASCII_SYMBOL_TYPE:
338 case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
339 case SHORT_SLICED_SYMBOL_TYPE:
340 case MEDIUM_SLICED_SYMBOL_TYPE:
341 case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL";
342 case SHORT_SLICED_ASCII_SYMBOL_TYPE:
343 case MEDIUM_SLICED_ASCII_SYMBOL_TYPE:
344 case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL";
345 case SHORT_CONS_SYMBOL_TYPE:
346 case MEDIUM_CONS_SYMBOL_TYPE:
347 case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
348 case SHORT_CONS_ASCII_SYMBOL_TYPE:
349 case MEDIUM_CONS_ASCII_SYMBOL_TYPE:
350 case LONG_CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
351 case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
352 case MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE:
353 case LONG_EXTERNAL_ASCII_SYMBOL_TYPE:
354 case SHORT_EXTERNAL_SYMBOL_TYPE:
355 case MEDIUM_EXTERNAL_SYMBOL_TYPE:
356 case LONG_EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
357 case SHORT_ASCII_STRING_TYPE:
358 case MEDIUM_ASCII_STRING_TYPE:
359 case LONG_ASCII_STRING_TYPE: return "ASCII_STRING";
360 case SHORT_STRING_TYPE:
361 case MEDIUM_STRING_TYPE:
362 case LONG_STRING_TYPE: return "TWO_BYTE_STRING";
363 case SHORT_CONS_STRING_TYPE:
364 case MEDIUM_CONS_STRING_TYPE:
365 case LONG_CONS_STRING_TYPE:
366 case SHORT_CONS_ASCII_STRING_TYPE:
367 case MEDIUM_CONS_ASCII_STRING_TYPE:
368 case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING";
369 case SHORT_SLICED_STRING_TYPE:
370 case MEDIUM_SLICED_STRING_TYPE:
371 case LONG_SLICED_STRING_TYPE:
372 case SHORT_SLICED_ASCII_STRING_TYPE:
373 case MEDIUM_SLICED_ASCII_STRING_TYPE:
374 case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING";
375 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
376 case MEDIUM_EXTERNAL_ASCII_STRING_TYPE:
377 case LONG_EXTERNAL_ASCII_STRING_TYPE:
378 case SHORT_EXTERNAL_STRING_TYPE:
379 case MEDIUM_EXTERNAL_STRING_TYPE:
380 case LONG_EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
381 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
382 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
383 case FILLER_TYPE: return "FILLER";
384 case JS_OBJECT_TYPE: return "JS_OBJECT";
385 case ODDBALL_TYPE: return "ODDBALL";
386 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
387 case JS_FUNCTION_TYPE: return "JS_FUNCTION";
388 case CODE_TYPE: return "CODE";
389 case JS_ARRAY_TYPE: return "JS_ARRAY";
ager@chromium.org236ad962008-09-25 09:45:57 +0000390 case JS_REGEXP_TYPE: return "JS_REGEXP";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000391 case JS_VALUE_TYPE: return "JS_VALUE";
392 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
393 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000394 case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000395 case PROXY_TYPE: return "PROXY";
396 case SMI_TYPE: return "SMI";
397#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
398 STRUCT_LIST(MAKE_STRUCT_CASE)
399#undef MAKE_STRUCT_CASE
400 }
401 return "UNKNOWN";
402}
403
404
405void Map::MapPrint() {
406 HeapObject::PrintHeader("Map");
407 PrintF(" - type: %s\n", TypeToString(instance_type()));
408 PrintF(" - instance size: %d\n", instance_size());
409 PrintF(" - unused property fields: %d\n", unused_property_fields());
410 PrintF(" - instance descriptors: ");
411 instance_descriptors()->ShortPrint();
412 PrintF("\n - prototype: ");
413 prototype()->ShortPrint();
414 PrintF("\n - constructor: ");
415 constructor()->ShortPrint();
416 PrintF("\n");
417}
418
419
420void Map::MapVerify() {
421 ASSERT(!Heap::InNewSpace(this));
422 ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
423 ASSERT(kPointerSize <= instance_size()
424 && instance_size() < Heap::Capacity());
425 VerifyHeapPointer(prototype());
426 VerifyHeapPointer(instance_descriptors());
427}
428
429
430void FixedArray::FixedArrayPrint() {
431 HeapObject::PrintHeader("FixedArray");
432 PrintF(" - length: %d", length());
433 for (int i = 0; i < length(); i++) {
434 PrintF("\n [%d]: ", i);
435 get(i)->ShortPrint();
436 }
437 PrintF("\n");
438}
439
440
441void FixedArray::FixedArrayVerify() {
442 for (int i = 0; i < length(); i++) {
443 Object* e = get(i);
444 if (e->IsHeapObject()) {
445 VerifyHeapPointer(e);
446 } else {
447 e->Verify();
448 }
449 }
450}
451
452
453void JSValue::JSValuePrint() {
454 HeapObject::PrintHeader("ValueObject");
455 value()->Print();
456}
457
458
459void JSValue::JSValueVerify() {
460 Object* v = value();
461 if (v->IsHeapObject()) {
462 VerifyHeapPointer(v);
463 }
464}
465
466
467void String::StringPrint() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000468 StringShape shape(this);
469 if (shape.IsSymbol()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000470 PrintF("#");
ager@chromium.org870a0b62008-11-04 11:43:05 +0000471 } else if (shape.IsCons()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000472 PrintF("c\"");
473 } else {
474 PrintF("\"");
475 }
476
477 for (int i = 0; i < length(); i++) {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000478 PrintF("%c", Get(shape, i));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 }
480
ager@chromium.org870a0b62008-11-04 11:43:05 +0000481 if (!shape.IsSymbol()) PrintF("\"");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000482}
483
484
485void String::StringVerify() {
486 CHECK(IsString());
487 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
488 if (IsSymbol()) {
489 CHECK(!Heap::InNewSpace(this));
490 }
491}
492
493
494void JSFunction::JSFunctionPrint() {
495 HeapObject::PrintHeader("Function");
496 PrintF(" - map = 0x%p\n", map());
497 PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no");
498 PrintF(" - initial_map = ");
499 if (has_initial_map()) {
500 initial_map()->ShortPrint();
501 }
502 PrintF("\n - shared_info = ");
503 shared()->ShortPrint();
504 PrintF("\n - name = ");
505 shared()->name()->Print();
506 PrintF("\n - context = ");
507 unchecked_context()->ShortPrint();
508 PrintF("\n - code = ");
509 code()->ShortPrint();
510 PrintF("\n");
511
512 PrintProperties();
513 PrintElements();
514
515 PrintF("\n");
516}
517
518
519void JSFunction::JSFunctionVerify() {
520 CHECK(IsJSFunction());
521 VerifyObjectField(kPrototypeOrInitialMapOffset);
522}
523
524
525void SharedFunctionInfo::SharedFunctionInfoPrint() {
526 HeapObject::PrintHeader("SharedFunctionInfo");
527 PrintF(" - name: ");
528 name()->ShortPrint();
529 PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
530 PrintF("\n - instance class name =");
531 instance_class_name()->Print();
532 PrintF("\n - code =");
533 code()->ShortPrint();
534 PrintF("\n - source code =");
535 GetSourceCode()->ShortPrint();
536 PrintF("\n - lazy load: %s",
537 lazy_load_data() == Heap::undefined_value() ? "no" : "yes");
538 // Script files are often large, hard to read.
539 // PrintF("\n - script =");
540 // script()->Print();
541 PrintF("\n - function token position = %d", function_token_position());
542 PrintF("\n - start position = %d", start_position());
543 PrintF("\n - end position = %d", end_position());
544 PrintF("\n - is expression = %d", is_expression());
545 PrintF("\n - debug info = ");
546 debug_info()->Print();
547 PrintF("\n - length = %d", length());
548 PrintF("\n");
549}
550
551void SharedFunctionInfo::SharedFunctionInfoVerify() {
552 CHECK(IsSharedFunctionInfo());
553 VerifyObjectField(kNameOffset);
554 VerifyObjectField(kCodeOffset);
555 VerifyObjectField(kInstanceClassNameOffset);
556 VerifyObjectField(kExternalReferenceDataOffset);
557 VerifyObjectField(kLazyLoadDataOffset);
558 VerifyObjectField(kScriptOffset);
559 VerifyObjectField(kDebugInfoOffset);
560}
561
562
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000563void JSGlobalProxy::JSGlobalProxyPrint() {
564 PrintF("global_proxy");
565 JSObjectPrint();
566 PrintF("context : ");
567 context()->ShortPrint();
568 PrintF("\n");
569}
570
571
572void JSGlobalProxy::JSGlobalProxyVerify() {
573 CHECK(IsJSGlobalProxy());
574 JSObjectVerify();
575 VerifyObjectField(JSGlobalProxy::kContextOffset);
576 // Make sure that this object has no properties, elements.
577 CHECK_EQ(0, properties()->length());
578 CHECK_EQ(0, elements()->length());
579}
580
581
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000582void JSGlobalObject::JSGlobalObjectPrint() {
583 PrintF("global ");
584 JSObjectPrint();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000585 PrintF("global context : ");
586 global_context()->ShortPrint();
587 PrintF("\n");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000588}
589
590
591void JSGlobalObject::JSGlobalObjectVerify() {
592 CHECK(IsJSGlobalObject());
593 JSObjectVerify();
594 for (int i = GlobalObject::kBuiltinsOffset;
595 i < JSGlobalObject::kSize;
596 i += kPointerSize) {
597 VerifyObjectField(i);
598 }
599}
600
601
602void JSBuiltinsObject::JSBuiltinsObjectPrint() {
603 PrintF("builtins ");
604 JSObjectPrint();
605}
606
607
608void JSBuiltinsObject::JSBuiltinsObjectVerify() {
609 CHECK(IsJSBuiltinsObject());
610 JSObjectVerify();
611 for (int i = GlobalObject::kBuiltinsOffset;
612 i < JSBuiltinsObject::kSize;
613 i += kPointerSize) {
614 VerifyObjectField(i);
615 }
616}
617
618
619void Oddball::OddballVerify() {
620 CHECK(IsOddball());
621 VerifyHeapPointer(to_string());
622 Object* number = to_number();
623 if (number->IsHeapObject()) {
624 ASSERT(number == Heap::nan_value());
625 } else {
626 ASSERT(number->IsSmi());
627 int value = Smi::cast(number)->value();
628 ASSERT(value == 0 || value == 1 || value == -1);
629 }
630}
631
632
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000633void Code::CodePrint() {
634 HeapObject::PrintHeader("Code");
mads.s.ager31e71382008-08-13 09:32:07 +0000635#ifdef ENABLE_DISASSEMBLER
636 Disassemble();
637#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
641void Code::CodeVerify() {
kasper.lund7276f142008-07-30 08:49:36 +0000642 CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
643 Address last_gc_pc = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644 for (RelocIterator it(this); !it.done(); it.next()) {
645 it.rinfo()->Verify();
kasper.lund7276f142008-07-30 08:49:36 +0000646 // Ensure that GC will not iterate twice over the same pointer.
ager@chromium.org236ad962008-09-25 09:45:57 +0000647 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
kasper.lund7276f142008-07-30 08:49:36 +0000648 CHECK(it.rinfo()->pc() != last_gc_pc);
649 last_gc_pc = it.rinfo()->pc();
650 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651 }
652}
653
654
655void JSArray::JSArrayVerify() {
656 JSObjectVerify();
657 ASSERT(length()->IsNumber() || length()->IsUndefined());
658 ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
659}
660
661
ager@chromium.org236ad962008-09-25 09:45:57 +0000662void JSRegExp::JSRegExpVerify() {
663 JSObjectVerify();
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000664 ASSERT(data()->IsUndefined() || data()->IsFixedArray());
665 switch (TypeTag()) {
666 case JSRegExp::ATOM: {
667 FixedArray* arr = FixedArray::cast(data());
668 ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
669 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000670 }
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000671 case JSRegExp::JSCRE: {
672 FixedArray* arr = FixedArray::cast(data());
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000673 Object* jscre_data = arr->get(JSRegExp::kJscreDataIndex);
674 ASSERT(jscre_data->IsFixedArray() || jscre_data->IsUndefined());
675 break;
676 }
677 case JSRegExp::IRREGEXP: {
678 FixedArray* arr = FixedArray::cast(data());
679 Object* jscre_data = arr->get(JSRegExp::kJscreDataIndex);
680 ASSERT(jscre_data->IsFixedArray());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000681 break;
682 }
683 default:
684 ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
685 ASSERT(data()->IsUndefined());
686 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000687 }
ager@chromium.org236ad962008-09-25 09:45:57 +0000688}
689
690
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000691void Proxy::ProxyPrint() {
692 PrintF("proxy to %p", proxy());
693}
694
695
696void Proxy::ProxyVerify() {
697 ASSERT(IsProxy());
698}
699
700
701void Dictionary::Print() {
702 int capacity = Capacity();
703 for (int i = 0; i < capacity; i++) {
704 Object* k = KeyAt(i);
705 if (IsKey(k)) {
706 PrintF(" ");
707 if (k->IsString()) {
708 String::cast(k)->StringPrint();
709 } else {
710 k->ShortPrint();
711 }
712 PrintF(": ");
713 ValueAt(i)->ShortPrint();
714 PrintF("\n");
715 }
716 }
717}
718
719
720void AccessorInfo::AccessorInfoVerify() {
721 CHECK(IsAccessorInfo());
722 VerifyPointer(getter());
723 VerifyPointer(setter());
724 VerifyPointer(name());
725 VerifyPointer(data());
726 VerifyPointer(flag());
727}
728
729void AccessorInfo::AccessorInfoPrint() {
730 PrintF("AccessorInfo");
731 PrintF("\n - getter: ");
732 getter()->ShortPrint();
733 PrintF("\n - setter: ");
734 setter()->ShortPrint();
735 PrintF("\n - name: ");
736 name()->ShortPrint();
737 PrintF("\n - data: ");
738 data()->ShortPrint();
739 PrintF("\n - flag: ");
740 flag()->ShortPrint();
741}
742
743void AccessCheckInfo::AccessCheckInfoVerify() {
744 CHECK(IsAccessCheckInfo());
745 VerifyPointer(named_callback());
746 VerifyPointer(indexed_callback());
747 VerifyPointer(data());
748}
749
750void AccessCheckInfo::AccessCheckInfoPrint() {
751 PrintF("AccessCheckInfo");
752 PrintF("\n - named_callback: ");
753 named_callback()->ShortPrint();
754 PrintF("\n - indexed_callback: ");
755 indexed_callback()->ShortPrint();
756 PrintF("\n - data: ");
757 data()->ShortPrint();
758}
759
760void InterceptorInfo::InterceptorInfoVerify() {
761 CHECK(IsInterceptorInfo());
762 VerifyPointer(getter());
763 VerifyPointer(setter());
764 VerifyPointer(query());
765 VerifyPointer(deleter());
766 VerifyPointer(enumerator());
767 VerifyPointer(data());
768}
769
770void InterceptorInfo::InterceptorInfoPrint() {
771 PrintF("InterceptorInfo");
772 PrintF("\n - getter: ");
773 getter()->ShortPrint();
774 PrintF("\n - setter: ");
775 setter()->ShortPrint();
776 PrintF("\n - query: ");
777 query()->ShortPrint();
778 PrintF("\n - deleter: ");
779 deleter()->ShortPrint();
780 PrintF("\n - enumerator: ");
781 enumerator()->ShortPrint();
782 PrintF("\n - data: ");
783 data()->ShortPrint();
784}
785
786void CallHandlerInfo::CallHandlerInfoVerify() {
787 CHECK(IsCallHandlerInfo());
788 VerifyPointer(callback());
789 VerifyPointer(data());
790}
791
792void CallHandlerInfo::CallHandlerInfoPrint() {
793 PrintF("CallHandlerInfo");
794 PrintF("\n - callback: ");
795 callback()->ShortPrint();
796 PrintF("\n - data: ");
797 data()->ShortPrint();
798}
799
800void TemplateInfo::TemplateInfoVerify() {
801 VerifyPointer(tag());
802 VerifyPointer(property_list());
803}
804
805void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
806 CHECK(IsFunctionTemplateInfo());
807 TemplateInfoVerify();
808 VerifyPointer(serial_number());
809 VerifyPointer(call_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000810 VerifyPointer(property_accessors());
811 VerifyPointer(prototype_template());
812 VerifyPointer(parent_template());
813 VerifyPointer(named_property_handler());
814 VerifyPointer(indexed_property_handler());
815 VerifyPointer(instance_template());
816 VerifyPointer(signature());
817 VerifyPointer(access_check_info());
818}
819
820void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
821 PrintF("FunctionTemplateInfo");
822 PrintF("\n - tag: ");
823 tag()->ShortPrint();
824 PrintF("\n - property_list: ");
825 property_list()->ShortPrint();
826 PrintF("\n - serial_number: ");
827 serial_number()->ShortPrint();
828 PrintF("\n - call_code: ");
829 call_code()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830 PrintF("\n - property_accessors: ");
831 property_accessors()->ShortPrint();
832 PrintF("\n - prototype_template: ");
833 prototype_template()->ShortPrint();
834 PrintF("\n - parent_template: ");
835 parent_template()->ShortPrint();
836 PrintF("\n - named_property_handler: ");
837 named_property_handler()->ShortPrint();
838 PrintF("\n - indexed_property_handler: ");
839 indexed_property_handler()->ShortPrint();
840 PrintF("\n - instance_template: ");
841 instance_template()->ShortPrint();
842 PrintF("\n - signature: ");
843 signature()->ShortPrint();
844 PrintF("\n - access_check_info: ");
845 access_check_info()->ShortPrint();
846 PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false");
847 PrintF("\n - undetectable: %s", undetectable() ? "true" : "false");
848 PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false");
849}
850
851void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
852 CHECK(IsObjectTemplateInfo());
853 TemplateInfoVerify();
854 VerifyPointer(constructor());
kasper.lund212ac232008-07-16 07:07:30 +0000855 VerifyPointer(internal_field_count());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000856}
857
858void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
859 PrintF("ObjectTemplateInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000860 PrintF("\n - constructor: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861 constructor()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000862 PrintF("\n - internal_field_count: ");
863 internal_field_count()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864}
865
866void SignatureInfo::SignatureInfoVerify() {
867 CHECK(IsSignatureInfo());
868 VerifyPointer(receiver());
869 VerifyPointer(args());
870}
871
872void SignatureInfo::SignatureInfoPrint() {
873 PrintF("SignatureInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000874 PrintF("\n - receiver: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875 receiver()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000876 PrintF("\n - args: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877 args()->ShortPrint();
878}
879
880void TypeSwitchInfo::TypeSwitchInfoVerify() {
881 CHECK(IsTypeSwitchInfo());
882 VerifyPointer(types());
883}
884
885void TypeSwitchInfo::TypeSwitchInfoPrint() {
886 PrintF("TypeSwitchInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000887 PrintF("\n - types: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000888 types()->ShortPrint();
889}
890
891
892void Script::ScriptVerify() {
893 CHECK(IsScript());
894 VerifyPointer(source());
895 VerifyPointer(name());
896 line_offset()->SmiVerify();
897 column_offset()->SmiVerify();
898 type()->SmiVerify();
899}
900
901
902void Script::ScriptPrint() {
903 HeapObject::PrintHeader("Script");
904 PrintF("\n - source: ");
905 source()->ShortPrint();
906 PrintF("\n - name: ");
907 name()->ShortPrint();
908 PrintF("\n - line_offset: ");
909 line_offset()->ShortPrint();
910 PrintF("\n - column_offset: ");
911 column_offset()->ShortPrint();
912 PrintF("\n - type: ");
913 type()->ShortPrint();
914 PrintF("\n");
915}
916
917
918void DebugInfo::DebugInfoVerify() {
919 CHECK(IsDebugInfo());
920 VerifyPointer(shared());
921 VerifyPointer(original_code());
922 VerifyPointer(code());
923 VerifyPointer(break_points());
924}
925
926
927void DebugInfo::DebugInfoPrint() {
928 PrintF("DebugInfo");
929 PrintF("\n - shared");
930 shared()->ShortPrint();
931 PrintF("\n - original_code");
932 original_code()->ShortPrint();
933 PrintF("\n - code");
934 code()->ShortPrint();
935 PrintF("\n - break_points");
936 break_points()->ShortPrint();
937}
938
939
940void BreakPointInfo::BreakPointInfoVerify() {
941 CHECK(IsBreakPointInfo());
942 code_position()->SmiVerify();
943 source_position()->SmiVerify();
944 statement_position()->SmiVerify();
945 VerifyPointer(break_point_objects());
946}
947
948
949void BreakPointInfo::BreakPointInfoPrint() {
950 PrintF("BreakPointInfo");
951 PrintF("\n - code_position %d", code_position());
952 PrintF("\n - source_position %d", source_position());
953 PrintF("\n - statement_position %d", statement_position());
954 PrintF("\n - break_point_objects ");
955 break_point_objects()->ShortPrint();
956}
957
958
959void JSObject::IncrementSpillStatistics(SpillInformation* info) {
960 info->number_of_objects_++;
961 // Named properties
962 if (HasFastProperties()) {
963 info->number_of_objects_with_fast_properties_++;
964 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
965 info->number_of_fast_unused_fields_ += map()->unused_property_fields();
966 } else {
967 Dictionary* dict = property_dictionary();
968 info->number_of_slow_used_properties_ += dict->NumberOfElements();
969 info->number_of_slow_unused_properties_ +=
970 dict->Capacity() - dict->NumberOfElements();
971 }
972 // Indexed properties
973 if (HasFastElements()) {
974 info->number_of_objects_with_fast_elements_++;
975 int holes = 0;
976 FixedArray* e = FixedArray::cast(elements());
977 int len = e->length();
978 for (int i = 0; i < len; i++) {
979 if (e->get(i) == Heap::the_hole_value()) holes++;
980 }
981 info->number_of_fast_used_elements_ += len - holes;
982 info->number_of_fast_unused_elements_ += holes;
983 } else {
984 Dictionary* dict = element_dictionary();
985 info->number_of_slow_used_elements_ += dict->NumberOfElements();
986 info->number_of_slow_unused_elements_ +=
987 dict->Capacity() - dict->NumberOfElements();
988 }
989}
990
991
992void JSObject::SpillInformation::Clear() {
993 number_of_objects_ = 0;
994 number_of_objects_with_fast_properties_ = 0;
995 number_of_objects_with_fast_elements_ = 0;
996 number_of_fast_used_fields_ = 0;
997 number_of_fast_unused_fields_ = 0;
998 number_of_slow_used_properties_ = 0;
999 number_of_slow_unused_properties_ = 0;
1000 number_of_fast_used_elements_ = 0;
1001 number_of_fast_unused_elements_ = 0;
1002 number_of_slow_used_elements_ = 0;
1003 number_of_slow_unused_elements_ = 0;
1004}
1005
1006void JSObject::SpillInformation::Print() {
1007 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
1008
1009 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
1010 number_of_objects_with_fast_properties_,
1011 number_of_fast_used_fields_, number_of_fast_unused_fields_);
1012
1013 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
1014 number_of_objects_ - number_of_objects_with_fast_properties_,
1015 number_of_slow_used_properties_, number_of_slow_unused_properties_);
1016
1017 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
1018 number_of_objects_with_fast_elements_,
1019 number_of_fast_used_elements_, number_of_fast_unused_elements_);
1020
1021 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
1022 number_of_objects_ - number_of_objects_with_fast_elements_,
1023 number_of_slow_used_elements_, number_of_slow_unused_elements_);
1024
1025 PrintF("\n");
1026}
1027
1028
1029void DescriptorArray::PrintDescriptors() {
1030 PrintF("Descriptor array %d\n", number_of_descriptors());
1031 int number = 0;
1032 for (DescriptorReader r(this); !r.eos(); r.advance()) {
1033 Descriptor desc;
1034 r.Get(&desc);
1035 PrintF(" %d: ", number++);
1036 desc.Print();
1037 }
1038 PrintF("\n");
1039}
1040
1041
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001042bool DescriptorArray::IsSortedNoDuplicates() {
1043 String* current_key = NULL;
1044 uint32_t current = 0;
1045 for (DescriptorReader r(this); !r.eos(); r.advance()) {
1046 String* key = r.GetKey();
1047 if (key == current_key) {
1048 PrintDescriptors();
1049 return false;
1050 }
1051 current_key = key;
1052 uint32_t hash = r.GetKey()->Hash();
1053 if (hash < current) {
1054 PrintDescriptors();
1055 return false;
1056 }
1057 current = hash;
1058 }
1059 return true;
1060}
1061
1062
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001063#endif // DEBUG
1064
1065} } // namespace v8::internal