OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 || (std::isnan(this_value) && std::isnan(other_value)); | 956 || (std::isnan(this_value) && std::isnan(other_value)); |
957 } | 957 } |
958 if (IsString() && other->IsString()) { | 958 if (IsString() && other->IsString()) { |
959 return String::cast(this)->Equals(String::cast(other)); | 959 return String::cast(this)->Equals(String::cast(other)); |
960 } | 960 } |
961 return false; | 961 return false; |
962 } | 962 } |
963 | 963 |
964 | 964 |
965 void Object::ShortPrint(FILE* out) { | 965 void Object::ShortPrint(FILE* out) { |
966 HeapStringAllocator allocator; | 966 OFStream os(out); |
967 StringStream accumulator(&allocator); | 967 os << Brief(this); |
968 ShortPrint(&accumulator); | |
969 accumulator.OutputToFile(out); | |
970 } | 968 } |
971 | 969 |
972 | 970 |
973 void Object::ShortPrint(StringStream* accumulator) { | 971 void Object::ShortPrint(StringStream* accumulator) { |
974 if (IsSmi()) { | 972 OStringStream os; |
975 Smi::cast(this)->SmiPrint(accumulator); | 973 os << Brief(this); |
976 } else { | 974 accumulator->Add(os.c_str()); |
977 HeapObject::cast(this)->HeapObjectShortPrint(accumulator); | |
978 } | |
979 } | 975 } |
980 | 976 |
981 | 977 |
982 void Smi::SmiPrint(FILE* out) { | 978 OStream& operator<<(OStream& os, const Brief& v) { |
983 PrintF(out, "%d", value()); | 979 if (v.value->IsSmi()) { |
| 980 Smi::cast(v.value)->SmiPrint(os); |
| 981 } else { |
| 982 // TODO(svenpanne) Const-correct HeapObjectShortPrint! |
| 983 HeapObject* obj = const_cast<HeapObject*>(HeapObject::cast(v.value)); |
| 984 obj->HeapObjectShortPrint(os); |
| 985 } |
| 986 return os; |
984 } | 987 } |
985 | 988 |
986 | 989 |
987 void Smi::SmiPrint(StringStream* accumulator) { | 990 void Smi::SmiPrint(OStream& os) const { // NOLINT |
988 accumulator->Add("%d", value()); | 991 os << value(); |
989 } | 992 } |
990 | 993 |
991 | 994 |
992 // Should a word be prefixed by 'a' or 'an' in order to read naturally in | 995 // Should a word be prefixed by 'a' or 'an' in order to read naturally in |
993 // English? Returns false for non-ASCII or words that don't start with | 996 // English? Returns false for non-ASCII or words that don't start with |
994 // a capital letter. The a/an rule follows pronunciation in English. | 997 // a capital letter. The a/an rule follows pronunciation in English. |
995 // We don't use the BBC's overcorrect "an historic occasion" though if | 998 // We don't use the BBC's overcorrect "an historic occasion" though if |
996 // you speak a dialect you may well say "an 'istoric occasion". | 999 // you speak a dialect you may well say "an 'istoric occasion". |
997 static bool AnWord(String* str) { | 1000 static bool AnWord(String* str) { |
998 if (str->length() == 0) return false; // A nothing. | 1001 if (str->length() == 0) return false; // A nothing. |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 accumulator->Put('.'); | 1237 accumulator->Put('.'); |
1235 accumulator->Put('.'); | 1238 accumulator->Put('.'); |
1236 accumulator->Put('.'); | 1239 accumulator->Put('.'); |
1237 } | 1240 } |
1238 accumulator->Put('>'); | 1241 accumulator->Put('>'); |
1239 } | 1242 } |
1240 return; | 1243 return; |
1241 } | 1244 } |
1242 | 1245 |
1243 | 1246 |
| 1247 void String::PrintUC16(OStream& os, int start, int end) { // NOLINT |
| 1248 if (end < 0) end = length(); |
| 1249 ConsStringIteratorOp op; |
| 1250 StringCharacterStream stream(this, &op, start); |
| 1251 for (int i = start; i < end && stream.HasMore(); i++) { |
| 1252 os << AsUC16(stream.GetNext()); |
| 1253 } |
| 1254 } |
| 1255 |
| 1256 |
1244 void JSObject::JSObjectShortPrint(StringStream* accumulator) { | 1257 void JSObject::JSObjectShortPrint(StringStream* accumulator) { |
1245 switch (map()->instance_type()) { | 1258 switch (map()->instance_type()) { |
1246 case JS_ARRAY_TYPE: { | 1259 case JS_ARRAY_TYPE: { |
1247 double length = JSArray::cast(this)->length()->IsUndefined() | 1260 double length = JSArray::cast(this)->length()->IsUndefined() |
1248 ? 0 | 1261 ? 0 |
1249 : JSArray::cast(this)->length()->Number(); | 1262 : JSArray::cast(this)->length()->Number(); |
1250 accumulator->Add("<JS Array[%u]>", static_cast<uint32_t>(length)); | 1263 accumulator->Add("<JS Array[%u]>", static_cast<uint32_t>(length)); |
1251 break; | 1264 break; |
1252 } | 1265 } |
1253 case JS_WEAK_MAP_TYPE: { | 1266 case JS_WEAK_MAP_TYPE: { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 } | 1350 } |
1338 } | 1351 } |
1339 } | 1352 } |
1340 | 1353 |
1341 | 1354 |
1342 void JSObject::PrintElementsTransition( | 1355 void JSObject::PrintElementsTransition( |
1343 FILE* file, Handle<JSObject> object, | 1356 FILE* file, Handle<JSObject> object, |
1344 ElementsKind from_kind, Handle<FixedArrayBase> from_elements, | 1357 ElementsKind from_kind, Handle<FixedArrayBase> from_elements, |
1345 ElementsKind to_kind, Handle<FixedArrayBase> to_elements) { | 1358 ElementsKind to_kind, Handle<FixedArrayBase> to_elements) { |
1346 if (from_kind != to_kind) { | 1359 if (from_kind != to_kind) { |
1347 PrintF(file, "elements transition ["); | 1360 OFStream os(file); |
1348 PrintElementsKind(file, from_kind); | 1361 os << "elements transition [" << ElementsKindToString(from_kind) << " -> " |
1349 PrintF(file, " -> "); | 1362 << ElementsKindToString(to_kind) << "] in "; |
1350 PrintElementsKind(file, to_kind); | |
1351 PrintF(file, "] in "); | |
1352 JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true); | 1363 JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true); |
1353 PrintF(file, " for "); | 1364 PrintF(file, " for "); |
1354 object->ShortPrint(file); | 1365 object->ShortPrint(file); |
1355 PrintF(file, " from "); | 1366 PrintF(file, " from "); |
1356 from_elements->ShortPrint(file); | 1367 from_elements->ShortPrint(file); |
1357 PrintF(file, " to "); | 1368 PrintF(file, " to "); |
1358 to_elements->ShortPrint(file); | 1369 to_elements->ShortPrint(file); |
1359 PrintF(file, "\n"); | 1370 PrintF(file, "\n"); |
1360 } | 1371 } |
1361 } | 1372 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 } else { | 1436 } else { |
1426 PrintF(file, "{symbol %p}", static_cast<void*>(name)); | 1437 PrintF(file, "{symbol %p}", static_cast<void*>(name)); |
1427 } | 1438 } |
1428 PrintF(file, " "); | 1439 PrintF(file, " "); |
1429 } | 1440 } |
1430 } | 1441 } |
1431 PrintF(file, "\n"); | 1442 PrintF(file, "\n"); |
1432 } | 1443 } |
1433 | 1444 |
1434 | 1445 |
1435 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { | 1446 void HeapObject::HeapObjectShortPrint(OStream& os) { // NOLINT |
1436 Heap* heap = GetHeap(); | 1447 Heap* heap = GetHeap(); |
1437 if (!heap->Contains(this)) { | 1448 if (!heap->Contains(this)) { |
1438 accumulator->Add("!!!INVALID POINTER!!!"); | 1449 os << "!!!INVALID POINTER!!!"; |
1439 return; | 1450 return; |
1440 } | 1451 } |
1441 if (!heap->Contains(map())) { | 1452 if (!heap->Contains(map())) { |
1442 accumulator->Add("!!!INVALID MAP!!!"); | 1453 os << "!!!INVALID MAP!!!"; |
1443 return; | 1454 return; |
1444 } | 1455 } |
1445 | 1456 |
1446 accumulator->Add("%p ", this); | 1457 os << this << " "; |
1447 | 1458 |
1448 if (IsString()) { | 1459 if (IsString()) { |
1449 String::cast(this)->StringShortPrint(accumulator); | 1460 HeapStringAllocator allocator; |
| 1461 StringStream accumulator(&allocator); |
| 1462 String::cast(this)->StringShortPrint(&accumulator); |
| 1463 os << accumulator.ToCString().get(); |
1450 return; | 1464 return; |
1451 } | 1465 } |
1452 if (IsJSObject()) { | 1466 if (IsJSObject()) { |
1453 JSObject::cast(this)->JSObjectShortPrint(accumulator); | 1467 HeapStringAllocator allocator; |
| 1468 StringStream accumulator(&allocator); |
| 1469 JSObject::cast(this)->JSObjectShortPrint(&accumulator); |
| 1470 os << accumulator.ToCString().get(); |
1454 return; | 1471 return; |
1455 } | 1472 } |
1456 switch (map()->instance_type()) { | 1473 switch (map()->instance_type()) { |
1457 case MAP_TYPE: | 1474 case MAP_TYPE: |
1458 accumulator->Add("<Map(elements=%u)>", Map::cast(this)->elements_kind()); | 1475 os << "<Map(elements=" << Map::cast(this)->elements_kind() << ")>"; |
1459 break; | 1476 break; |
1460 case FIXED_ARRAY_TYPE: | 1477 case FIXED_ARRAY_TYPE: |
1461 accumulator->Add("<FixedArray[%u]>", FixedArray::cast(this)->length()); | 1478 os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>"; |
1462 break; | 1479 break; |
1463 case FIXED_DOUBLE_ARRAY_TYPE: | 1480 case FIXED_DOUBLE_ARRAY_TYPE: |
1464 accumulator->Add("<FixedDoubleArray[%u]>", | 1481 os << "<FixedDoubleArray[" << FixedDoubleArray::cast(this)->length() |
1465 FixedDoubleArray::cast(this)->length()); | 1482 << "]>"; |
1466 break; | 1483 break; |
1467 case BYTE_ARRAY_TYPE: | 1484 case BYTE_ARRAY_TYPE: |
1468 accumulator->Add("<ByteArray[%u]>", ByteArray::cast(this)->length()); | 1485 os << "<ByteArray[" << ByteArray::cast(this)->length() << "]>"; |
1469 break; | 1486 break; |
1470 case FREE_SPACE_TYPE: | 1487 case FREE_SPACE_TYPE: |
1471 accumulator->Add("<FreeSpace[%u]>", FreeSpace::cast(this)->Size()); | 1488 os << "<FreeSpace[" << FreeSpace::cast(this)->Size() << "]>"; |
1472 break; | 1489 break; |
1473 #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size) \ | 1490 #define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size) \ |
1474 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 1491 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
1475 accumulator->Add("<External" #Type "Array[%u]>", \ | 1492 os << "<External" #Type "Array[" \ |
1476 External##Type##Array::cast(this)->length()); \ | 1493 << External##Type##Array::cast(this)->length() << "]>"; \ |
1477 break; \ | 1494 break; \ |
1478 case FIXED_##TYPE##_ARRAY_TYPE: \ | 1495 case FIXED_##TYPE##_ARRAY_TYPE: \ |
1479 accumulator->Add("<Fixed" #Type "Array[%u]>", \ | 1496 os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(this)->length() \ |
1480 Fixed##Type##Array::cast(this)->length()); \ | 1497 << "]>"; \ |
1481 break; | 1498 break; |
1482 | 1499 |
1483 TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT) | 1500 TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT) |
1484 #undef TYPED_ARRAY_SHORT_PRINT | 1501 #undef TYPED_ARRAY_SHORT_PRINT |
1485 | 1502 |
1486 case SHARED_FUNCTION_INFO_TYPE: { | 1503 case SHARED_FUNCTION_INFO_TYPE: { |
1487 SharedFunctionInfo* shared = SharedFunctionInfo::cast(this); | 1504 SharedFunctionInfo* shared = SharedFunctionInfo::cast(this); |
1488 SmartArrayPointer<char> debug_name = | 1505 SmartArrayPointer<char> debug_name = |
1489 shared->DebugName()->ToCString(); | 1506 shared->DebugName()->ToCString(); |
1490 if (debug_name[0] != 0) { | 1507 if (debug_name[0] != 0) { |
1491 accumulator->Add("<SharedFunctionInfo %s>", debug_name.get()); | 1508 os << "<SharedFunctionInfo " << debug_name.get() << ">"; |
1492 } else { | 1509 } else { |
1493 accumulator->Add("<SharedFunctionInfo>"); | 1510 os << "<SharedFunctionInfo>"; |
1494 } | 1511 } |
1495 break; | 1512 break; |
1496 } | 1513 } |
1497 case JS_MESSAGE_OBJECT_TYPE: | 1514 case JS_MESSAGE_OBJECT_TYPE: |
1498 accumulator->Add("<JSMessageObject>"); | 1515 os << "<JSMessageObject>"; |
1499 break; | 1516 break; |
1500 #define MAKE_STRUCT_CASE(NAME, Name, name) \ | 1517 #define MAKE_STRUCT_CASE(NAME, Name, name) \ |
1501 case NAME##_TYPE: \ | 1518 case NAME##_TYPE: \ |
1502 accumulator->Put('<'); \ | 1519 os << "<" #Name ">"; \ |
1503 accumulator->Add(#Name); \ | |
1504 accumulator->Put('>'); \ | |
1505 break; | 1520 break; |
1506 STRUCT_LIST(MAKE_STRUCT_CASE) | 1521 STRUCT_LIST(MAKE_STRUCT_CASE) |
1507 #undef MAKE_STRUCT_CASE | 1522 #undef MAKE_STRUCT_CASE |
1508 case CODE_TYPE: | 1523 case CODE_TYPE: |
1509 accumulator->Add("<Code>"); | 1524 os << "<Code>"; |
1510 break; | 1525 break; |
1511 case ODDBALL_TYPE: { | 1526 case ODDBALL_TYPE: { |
1512 if (IsUndefined()) | 1527 if (IsUndefined()) { |
1513 accumulator->Add("<undefined>"); | 1528 os << "<undefined>"; |
1514 else if (IsTheHole()) | 1529 } else if (IsTheHole()) { |
1515 accumulator->Add("<the hole>"); | 1530 os << "<the hole>"; |
1516 else if (IsNull()) | 1531 } else if (IsNull()) { |
1517 accumulator->Add("<null>"); | 1532 os << "<null>"; |
1518 else if (IsTrue()) | 1533 } else if (IsTrue()) { |
1519 accumulator->Add("<true>"); | 1534 os << "<true>"; |
1520 else if (IsFalse()) | 1535 } else if (IsFalse()) { |
1521 accumulator->Add("<false>"); | 1536 os << "<false>"; |
1522 else | 1537 } else { |
1523 accumulator->Add("<Odd Oddball>"); | 1538 os << "<Odd Oddball>"; |
| 1539 } |
1524 break; | 1540 break; |
1525 } | 1541 } |
1526 case SYMBOL_TYPE: { | 1542 case SYMBOL_TYPE: { |
1527 Symbol* symbol = Symbol::cast(this); | 1543 Symbol* symbol = Symbol::cast(this); |
1528 accumulator->Add("<Symbol: %d", symbol->Hash()); | 1544 os << "<Symbol: " << symbol->Hash(); |
1529 if (!symbol->name()->IsUndefined()) { | 1545 if (!symbol->name()->IsUndefined()) { |
1530 accumulator->Add(" "); | 1546 os << " "; |
1531 String::cast(symbol->name())->StringShortPrint(accumulator); | 1547 HeapStringAllocator allocator; |
| 1548 StringStream accumulator(&allocator); |
| 1549 String::cast(symbol->name())->StringShortPrint(&accumulator); |
| 1550 os << accumulator.ToCString().get(); |
1532 } | 1551 } |
1533 accumulator->Add(">"); | 1552 os << ">"; |
1534 break; | 1553 break; |
1535 } | 1554 } |
1536 case HEAP_NUMBER_TYPE: | 1555 case HEAP_NUMBER_TYPE: { |
1537 accumulator->Add("<Number: "); | 1556 os << "<Number: "; |
1538 HeapNumber::cast(this)->HeapNumberPrint(accumulator); | 1557 HeapNumber::cast(this)->HeapNumberPrint(os); |
1539 accumulator->Put('>'); | 1558 os << ">"; |
1540 break; | 1559 break; |
1541 case MUTABLE_HEAP_NUMBER_TYPE: | 1560 } |
1542 accumulator->Add("<MutableNumber: "); | 1561 case MUTABLE_HEAP_NUMBER_TYPE: { |
1543 HeapNumber::cast(this)->HeapNumberPrint(accumulator); | 1562 os << "<MutableNumber: "; |
1544 accumulator->Put('>'); | 1563 HeapNumber::cast(this)->HeapNumberPrint(os); |
| 1564 os << '>'; |
1545 break; | 1565 break; |
| 1566 } |
1546 case JS_PROXY_TYPE: | 1567 case JS_PROXY_TYPE: |
1547 accumulator->Add("<JSProxy>"); | 1568 os << "<JSProxy>"; |
1548 break; | 1569 break; |
1549 case JS_FUNCTION_PROXY_TYPE: | 1570 case JS_FUNCTION_PROXY_TYPE: |
1550 accumulator->Add("<JSFunctionProxy>"); | 1571 os << "<JSFunctionProxy>"; |
1551 break; | 1572 break; |
1552 case FOREIGN_TYPE: | 1573 case FOREIGN_TYPE: |
1553 accumulator->Add("<Foreign>"); | 1574 os << "<Foreign>"; |
1554 break; | 1575 break; |
1555 case CELL_TYPE: | 1576 case CELL_TYPE: { |
1556 accumulator->Add("Cell for "); | 1577 os << "Cell for "; |
1557 Cell::cast(this)->value()->ShortPrint(accumulator); | 1578 HeapStringAllocator allocator; |
| 1579 StringStream accumulator(&allocator); |
| 1580 Cell::cast(this)->value()->ShortPrint(&accumulator); |
| 1581 os << accumulator.ToCString().get(); |
1558 break; | 1582 break; |
1559 case PROPERTY_CELL_TYPE: | 1583 } |
1560 accumulator->Add("PropertyCell for "); | 1584 case PROPERTY_CELL_TYPE: { |
1561 PropertyCell::cast(this)->value()->ShortPrint(accumulator); | 1585 os << "PropertyCell for "; |
| 1586 HeapStringAllocator allocator; |
| 1587 StringStream accumulator(&allocator); |
| 1588 PropertyCell::cast(this)->value()->ShortPrint(&accumulator); |
| 1589 os << accumulator.ToCString().get(); |
1562 break; | 1590 break; |
| 1591 } |
1563 default: | 1592 default: |
1564 accumulator->Add("<Other heap object (%d)>", map()->instance_type()); | 1593 os << "<Other heap object (" << map()->instance_type() << ")>"; |
1565 break; | 1594 break; |
1566 } | 1595 } |
1567 } | 1596 } |
1568 | 1597 |
1569 | 1598 |
1570 void HeapObject::Iterate(ObjectVisitor* v) { | 1599 void HeapObject::Iterate(ObjectVisitor* v) { |
1571 // Handle header | 1600 // Handle header |
1572 IteratePointer(v, kMapOffset); | 1601 IteratePointer(v, kMapOffset); |
1573 // Handle object body | 1602 // Handle object body |
1574 Map* m = map(); | 1603 Map* m = map(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 UNREACHABLE(); | 1731 UNREACHABLE(); |
1703 } | 1732 } |
1704 } | 1733 } |
1705 | 1734 |
1706 | 1735 |
1707 bool HeapNumber::HeapNumberBooleanValue() { | 1736 bool HeapNumber::HeapNumberBooleanValue() { |
1708 return DoubleToBoolean(value()); | 1737 return DoubleToBoolean(value()); |
1709 } | 1738 } |
1710 | 1739 |
1711 | 1740 |
1712 void HeapNumber::HeapNumberPrint(FILE* out) { | 1741 void HeapNumber::HeapNumberPrint(OStream& os) { // NOLINT |
1713 PrintF(out, "%.16g", value()); | 1742 os << value(); |
1714 } | 1743 } |
1715 | 1744 |
1716 | 1745 |
1717 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { | |
1718 // The Windows version of vsnprintf can allocate when printing a %g string | |
1719 // into a buffer that may not be big enough. We don't want random memory | |
1720 // allocation when producing post-crash stack traces, so we print into a | |
1721 // buffer that is plenty big enough for any floating point number, then | |
1722 // print that using vsnprintf (which may truncate but never allocate if | |
1723 // there is no more space in the buffer). | |
1724 EmbeddedVector<char, 100> buffer; | |
1725 SNPrintF(buffer, "%.16g", value()); | |
1726 accumulator->Add("%s", buffer.start()); | |
1727 } | |
1728 | |
1729 | |
1730 String* JSReceiver::class_name() { | 1746 String* JSReceiver::class_name() { |
1731 if (IsJSFunction() && IsJSFunctionProxy()) { | 1747 if (IsJSFunction() && IsJSFunctionProxy()) { |
1732 return GetHeap()->function_class_string(); | 1748 return GetHeap()->function_class_string(); |
1733 } | 1749 } |
1734 if (map()->constructor()->IsJSFunction()) { | 1750 if (map()->constructor()->IsJSFunction()) { |
1735 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1751 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1736 return String::cast(constructor->shared()->instance_class_name()); | 1752 return String::cast(constructor->shared()->instance_class_name()); |
1737 } | 1753 } |
1738 // If the constructor is not present, return "Object". | 1754 // If the constructor is not present, return "Object". |
1739 return GetHeap()->Object_string(); | 1755 return GetHeap()->Object_string(); |
(...skipping 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4702 // We are storing the new map using release store after creating a filler for | 4718 // We are storing the new map using release store after creating a filler for |
4703 // the left-over space to avoid races with the sweeper thread. | 4719 // the left-over space to avoid races with the sweeper thread. |
4704 object->synchronized_set_map(*new_map); | 4720 object->synchronized_set_map(*new_map); |
4705 | 4721 |
4706 object->set_properties(*dictionary); | 4722 object->set_properties(*dictionary); |
4707 | 4723 |
4708 isolate->counters()->props_to_dictionary()->Increment(); | 4724 isolate->counters()->props_to_dictionary()->Increment(); |
4709 | 4725 |
4710 #ifdef DEBUG | 4726 #ifdef DEBUG |
4711 if (FLAG_trace_normalization) { | 4727 if (FLAG_trace_normalization) { |
4712 PrintF("Object properties have been normalized:\n"); | 4728 OFStream os(stdout); |
4713 object->Print(); | 4729 os << "Object properties have been normalized:\n"; |
| 4730 object->Print(os); |
4714 } | 4731 } |
4715 #endif | 4732 #endif |
4716 } | 4733 } |
4717 | 4734 |
4718 | 4735 |
4719 void JSObject::MigrateSlowToFast(Handle<JSObject> object, | 4736 void JSObject::MigrateSlowToFast(Handle<JSObject> object, |
4720 int unused_property_fields) { | 4737 int unused_property_fields) { |
4721 if (object->HasFastProperties()) return; | 4738 if (object->HasFastProperties()) return; |
4722 ASSERT(!object->IsGlobalObject()); | 4739 ASSERT(!object->IsGlobalObject()); |
4723 Isolate* isolate = object->GetIsolate(); | 4740 Isolate* isolate = object->GetIsolate(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4931 JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS); | 4948 JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS); |
4932 | 4949 |
4933 JSObject::MigrateToMap(object, new_map); | 4950 JSObject::MigrateToMap(object, new_map); |
4934 object->set_elements(*dictionary); | 4951 object->set_elements(*dictionary); |
4935 } | 4952 } |
4936 | 4953 |
4937 isolate->counters()->elements_to_dictionary()->Increment(); | 4954 isolate->counters()->elements_to_dictionary()->Increment(); |
4938 | 4955 |
4939 #ifdef DEBUG | 4956 #ifdef DEBUG |
4940 if (FLAG_trace_normalization) { | 4957 if (FLAG_trace_normalization) { |
4941 PrintF("Object elements have been normalized:\n"); | 4958 OFStream os(stdout); |
4942 object->Print(); | 4959 os << "Object elements have been normalized:\n"; |
| 4960 object->Print(os); |
4943 } | 4961 } |
4944 #endif | 4962 #endif |
4945 | 4963 |
4946 ASSERT(object->HasDictionaryElements() || | 4964 ASSERT(object->HasDictionaryElements() || |
4947 object->HasDictionaryArgumentsElements()); | 4965 object->HasDictionaryArgumentsElements()); |
4948 return dictionary; | 4966 return dictionary; |
4949 } | 4967 } |
4950 | 4968 |
4951 | 4969 |
4952 static Smi* GenerateIdentityHash(Isolate* isolate) { | 4970 static Smi* GenerateIdentityHash(Isolate* isolate) { |
(...skipping 5410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10363 } | 10381 } |
10364 | 10382 |
10365 | 10383 |
10366 String* SharedFunctionInfo::DebugName() { | 10384 String* SharedFunctionInfo::DebugName() { |
10367 Object* n = name(); | 10385 Object* n = name(); |
10368 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); | 10386 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); |
10369 return String::cast(n); | 10387 return String::cast(n); |
10370 } | 10388 } |
10371 | 10389 |
10372 | 10390 |
10373 bool SharedFunctionInfo::HasSourceCode() { | 10391 bool SharedFunctionInfo::HasSourceCode() const { |
10374 return !script()->IsUndefined() && | 10392 return !script()->IsUndefined() && |
10375 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); | 10393 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); |
10376 } | 10394 } |
10377 | 10395 |
10378 | 10396 |
10379 Handle<Object> SharedFunctionInfo::GetSourceCode() { | 10397 Handle<Object> SharedFunctionInfo::GetSourceCode() { |
10380 if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value(); | 10398 if (!HasSourceCode()) return GetIsolate()->factory()->undefined_value(); |
10381 Handle<String> source(String::cast(Script::cast(script())->source())); | 10399 Handle<String> source(String::cast(Script::cast(script())->source())); |
10382 return GetIsolate()->factory()->NewSubString( | 10400 return GetIsolate()->factory()->NewSubString( |
10383 source, start_position(), end_position()); | 10401 source, start_position(), end_position()); |
(...skipping 24 matching lines...) Expand all Loading... |
10408 } | 10426 } |
10409 return instance_size; | 10427 return instance_size; |
10410 } | 10428 } |
10411 | 10429 |
10412 | 10430 |
10413 int SharedFunctionInfo::CalculateInObjectProperties() { | 10431 int SharedFunctionInfo::CalculateInObjectProperties() { |
10414 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; | 10432 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
10415 } | 10433 } |
10416 | 10434 |
10417 | 10435 |
10418 // Support function for printing the source code to a StringStream | 10436 // Output the source code without any allocation in the heap. |
10419 // without any allocation in the heap. | 10437 OStream& operator<<(OStream& os, const SourceCodeOf& v) { |
10420 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator, | 10438 const SharedFunctionInfo* s = v.value; |
10421 int max_length) { | |
10422 // For some native functions there is no source. | 10439 // For some native functions there is no source. |
10423 if (!HasSourceCode()) { | 10440 if (!s->HasSourceCode()) return os << "<No Source>"; |
10424 accumulator->Add("<No Source>"); | |
10425 return; | |
10426 } | |
10427 | 10441 |
10428 // Get the source for the script which this function came from. | 10442 // Get the source for the script which this function came from. |
10429 // Don't use String::cast because we don't want more assertion errors while | 10443 // Don't use String::cast because we don't want more assertion errors while |
10430 // we are already creating a stack dump. | 10444 // we are already creating a stack dump. |
10431 String* script_source = | 10445 String* script_source = |
10432 reinterpret_cast<String*>(Script::cast(script())->source()); | 10446 reinterpret_cast<String*>(Script::cast(s->script())->source()); |
10433 | 10447 |
10434 if (!script_source->LooksValid()) { | 10448 if (!script_source->LooksValid()) return os << "<Invalid Source>"; |
10435 accumulator->Add("<Invalid Source>"); | |
10436 return; | |
10437 } | |
10438 | 10449 |
10439 if (!is_toplevel()) { | 10450 if (!s->is_toplevel()) { |
10440 accumulator->Add("function "); | 10451 os << "function "; |
10441 Object* name = this->name(); | 10452 Object* name = s->name(); |
10442 if (name->IsString() && String::cast(name)->length() > 0) { | 10453 if (name->IsString() && String::cast(name)->length() > 0) { |
10443 accumulator->PrintName(name); | 10454 String::cast(name)->PrintUC16(os); |
10444 } | 10455 } |
10445 } | 10456 } |
10446 | 10457 |
10447 int len = end_position() - start_position(); | 10458 int len = s->end_position() - s->start_position(); |
10448 if (len <= max_length || max_length < 0) { | 10459 if (len <= v.max_length || v.max_length < 0) { |
10449 accumulator->Put(script_source, start_position(), end_position()); | 10460 script_source->PrintUC16(os, s->start_position(), s->end_position()); |
| 10461 return os; |
10450 } else { | 10462 } else { |
10451 accumulator->Put(script_source, | 10463 script_source->PrintUC16(os, s->start_position(), |
10452 start_position(), | 10464 s->start_position() + v.max_length); |
10453 start_position() + max_length); | 10465 return os << "...\n"; |
10454 accumulator->Add("...\n"); | |
10455 } | 10466 } |
10456 } | 10467 } |
10457 | 10468 |
10458 | 10469 |
10459 static bool IsCodeEquivalent(Code* code, Code* recompiled) { | 10470 static bool IsCodeEquivalent(Code* code, Code* recompiled) { |
10460 if (code->instruction_size() != recompiled->instruction_size()) return false; | 10471 if (code->instruction_size() != recompiled->instruction_size()) return false; |
10461 ByteArray* code_relocation = code->relocation_info(); | 10472 ByteArray* code_relocation = code->relocation_info(); |
10462 ByteArray* recompiled_relocation = recompiled->relocation_info(); | 10473 ByteArray* recompiled_relocation = recompiled->relocation_info(); |
10463 int length = code_relocation->length(); | 10474 int length = code_relocation->length(); |
10464 if (length != recompiled_relocation->length()) return false; | 10475 if (length != recompiled_relocation->length()) return false; |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11214 #undef CASE | 11225 #undef CASE |
11215 case NUMBER_OF_KINDS: break; | 11226 case NUMBER_OF_KINDS: break; |
11216 } | 11227 } |
11217 UNREACHABLE(); | 11228 UNREACHABLE(); |
11218 return NULL; | 11229 return NULL; |
11219 } | 11230 } |
11220 | 11231 |
11221 | 11232 |
11222 #ifdef ENABLE_DISASSEMBLER | 11233 #ifdef ENABLE_DISASSEMBLER |
11223 | 11234 |
11224 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) { | 11235 void DeoptimizationInputData::DeoptimizationInputDataPrint( |
| 11236 OStream& os) { // NOLINT |
11225 disasm::NameConverter converter; | 11237 disasm::NameConverter converter; |
11226 int deopt_count = DeoptCount(); | 11238 int deopt_count = DeoptCount(); |
11227 PrintF(out, "Deoptimization Input Data (deopt points = %d)\n", deopt_count); | 11239 os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n"; |
11228 if (0 == deopt_count) return; | 11240 if (0 == deopt_count) return; |
11229 | 11241 |
11230 PrintF(out, "%6s %6s %6s %6s %12s\n", "index", "ast id", "argc", "pc", | 11242 os << " index ast id argc pc"; |
11231 FLAG_print_code_verbose ? "commands" : ""); | 11243 if (FLAG_print_code_verbose) os << "commands"; |
| 11244 os << "\n"; |
11232 for (int i = 0; i < deopt_count; i++) { | 11245 for (int i = 0; i < deopt_count; i++) { |
11233 PrintF(out, "%6d %6d %6d %6d", | 11246 // TODO(svenpanne) Add some basic formatting to our streams. |
11234 i, | 11247 Vector<char> buf1 = Vector<char>::New(128); |
11235 AstId(i).ToInt(), | 11248 SNPrintF(buf1, "%6d %6d %6d %6d", i, AstId(i).ToInt(), |
11236 ArgumentsStackHeight(i)->value(), | 11249 ArgumentsStackHeight(i)->value(), Pc(i)->value()); |
11237 Pc(i)->value()); | 11250 os << buf1.start(); |
11238 | 11251 |
11239 if (!FLAG_print_code_verbose) { | 11252 if (!FLAG_print_code_verbose) { |
11240 PrintF(out, "\n"); | 11253 os << "\n"; |
11241 continue; | 11254 continue; |
11242 } | 11255 } |
11243 // Print details of the frame translation. | 11256 // Print details of the frame translation. |
11244 int translation_index = TranslationIndex(i)->value(); | 11257 int translation_index = TranslationIndex(i)->value(); |
11245 TranslationIterator iterator(TranslationByteArray(), translation_index); | 11258 TranslationIterator iterator(TranslationByteArray(), translation_index); |
11246 Translation::Opcode opcode = | 11259 Translation::Opcode opcode = |
11247 static_cast<Translation::Opcode>(iterator.Next()); | 11260 static_cast<Translation::Opcode>(iterator.Next()); |
11248 ASSERT(Translation::BEGIN == opcode); | 11261 ASSERT(Translation::BEGIN == opcode); |
11249 int frame_count = iterator.Next(); | 11262 int frame_count = iterator.Next(); |
11250 int jsframe_count = iterator.Next(); | 11263 int jsframe_count = iterator.Next(); |
11251 PrintF(out, " %s {frame count=%d, js frame count=%d}\n", | 11264 os << " " << Translation::StringFor(opcode) |
11252 Translation::StringFor(opcode), | 11265 << " {frame count=" << frame_count |
11253 frame_count, | 11266 << ", js frame count=" << jsframe_count << "}\n"; |
11254 jsframe_count); | |
11255 | 11267 |
11256 while (iterator.HasNext() && | 11268 while (iterator.HasNext() && |
11257 Translation::BEGIN != | 11269 Translation::BEGIN != |
11258 (opcode = static_cast<Translation::Opcode>(iterator.Next()))) { | 11270 (opcode = static_cast<Translation::Opcode>(iterator.Next()))) { |
11259 PrintF(out, "%24s %s ", "", Translation::StringFor(opcode)); | 11271 Vector<char> buf2 = Vector<char>::New(128); |
| 11272 SNPrintF(buf2, "%24s %s ", "", Translation::StringFor(opcode)); |
| 11273 os << buf2.start(); |
11260 | 11274 |
11261 switch (opcode) { | 11275 switch (opcode) { |
11262 case Translation::BEGIN: | 11276 case Translation::BEGIN: |
11263 UNREACHABLE(); | 11277 UNREACHABLE(); |
11264 break; | 11278 break; |
11265 | 11279 |
11266 case Translation::JS_FRAME: { | 11280 case Translation::JS_FRAME: { |
11267 int ast_id = iterator.Next(); | 11281 int ast_id = iterator.Next(); |
11268 int function_id = iterator.Next(); | 11282 int function_id = iterator.Next(); |
11269 unsigned height = iterator.Next(); | 11283 unsigned height = iterator.Next(); |
11270 PrintF(out, "{ast_id=%d, function=", ast_id); | 11284 os << "{ast_id=" << ast_id << ", function="; |
11271 if (function_id != Translation::kSelfLiteralId) { | 11285 if (function_id != Translation::kSelfLiteralId) { |
11272 Object* function = LiteralArray()->get(function_id); | 11286 Object* function = LiteralArray()->get(function_id); |
11273 JSFunction::cast(function)->PrintName(out); | 11287 os << Brief(JSFunction::cast(function)->shared()->DebugName()); |
11274 } else { | 11288 } else { |
11275 PrintF(out, "<self>"); | 11289 os << "<self>"; |
11276 } | 11290 } |
11277 PrintF(out, ", height=%u}", height); | 11291 os << ", height=" << height << "}"; |
11278 break; | 11292 break; |
11279 } | 11293 } |
11280 | 11294 |
11281 case Translation::COMPILED_STUB_FRAME: { | 11295 case Translation::COMPILED_STUB_FRAME: { |
11282 Code::Kind stub_kind = static_cast<Code::Kind>(iterator.Next()); | 11296 Code::Kind stub_kind = static_cast<Code::Kind>(iterator.Next()); |
11283 PrintF(out, "{kind=%d}", stub_kind); | 11297 os << "{kind=" << stub_kind << "}"; |
11284 break; | 11298 break; |
11285 } | 11299 } |
11286 | 11300 |
11287 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 11301 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
11288 case Translation::CONSTRUCT_STUB_FRAME: { | 11302 case Translation::CONSTRUCT_STUB_FRAME: { |
11289 int function_id = iterator.Next(); | 11303 int function_id = iterator.Next(); |
11290 JSFunction* function = | 11304 JSFunction* function = |
11291 JSFunction::cast(LiteralArray()->get(function_id)); | 11305 JSFunction::cast(LiteralArray()->get(function_id)); |
11292 unsigned height = iterator.Next(); | 11306 unsigned height = iterator.Next(); |
11293 PrintF(out, "{function="); | 11307 os << "{function=" << Brief(function->shared()->DebugName()) |
11294 function->PrintName(out); | 11308 << ", height=" << height << "}"; |
11295 PrintF(out, ", height=%u}", height); | |
11296 break; | 11309 break; |
11297 } | 11310 } |
11298 | 11311 |
11299 case Translation::GETTER_STUB_FRAME: | 11312 case Translation::GETTER_STUB_FRAME: |
11300 case Translation::SETTER_STUB_FRAME: { | 11313 case Translation::SETTER_STUB_FRAME: { |
11301 int function_id = iterator.Next(); | 11314 int function_id = iterator.Next(); |
11302 JSFunction* function = | 11315 JSFunction* function = |
11303 JSFunction::cast(LiteralArray()->get(function_id)); | 11316 JSFunction::cast(LiteralArray()->get(function_id)); |
11304 PrintF(out, "{function="); | 11317 os << "{function=" << Brief(function->shared()->DebugName()) << "}"; |
11305 function->PrintName(out); | |
11306 PrintF(out, "}"); | |
11307 break; | 11318 break; |
11308 } | 11319 } |
11309 | 11320 |
11310 case Translation::REGISTER: { | 11321 case Translation::REGISTER: { |
11311 int reg_code = iterator.Next(); | 11322 int reg_code = iterator.Next(); |
11312 PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code)); | 11323 os << "{input=" << converter.NameOfCPURegister(reg_code) << "}"; |
11313 break; | 11324 break; |
11314 } | 11325 } |
11315 | 11326 |
11316 case Translation::INT32_REGISTER: { | 11327 case Translation::INT32_REGISTER: { |
11317 int reg_code = iterator.Next(); | 11328 int reg_code = iterator.Next(); |
11318 PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code)); | 11329 os << "{input=" << converter.NameOfCPURegister(reg_code) << "}"; |
11319 break; | 11330 break; |
11320 } | 11331 } |
11321 | 11332 |
11322 case Translation::UINT32_REGISTER: { | 11333 case Translation::UINT32_REGISTER: { |
11323 int reg_code = iterator.Next(); | 11334 int reg_code = iterator.Next(); |
11324 PrintF(out, "{input=%s (unsigned)}", | 11335 os << "{input=" << converter.NameOfCPURegister(reg_code) |
11325 converter.NameOfCPURegister(reg_code)); | 11336 << " (unsigned)}"; |
11326 break; | 11337 break; |
11327 } | 11338 } |
11328 | 11339 |
11329 case Translation::DOUBLE_REGISTER: { | 11340 case Translation::DOUBLE_REGISTER: { |
11330 int reg_code = iterator.Next(); | 11341 int reg_code = iterator.Next(); |
11331 PrintF(out, "{input=%s}", | 11342 os << "{input=" << DoubleRegister::AllocationIndexToString(reg_code) |
11332 DoubleRegister::AllocationIndexToString(reg_code)); | 11343 << "}"; |
11333 break; | 11344 break; |
11334 } | 11345 } |
11335 | 11346 |
11336 case Translation::STACK_SLOT: { | 11347 case Translation::STACK_SLOT: { |
11337 int input_slot_index = iterator.Next(); | 11348 int input_slot_index = iterator.Next(); |
11338 PrintF(out, "{input=%d}", input_slot_index); | 11349 os << "{input=" << input_slot_index << "}"; |
11339 break; | 11350 break; |
11340 } | 11351 } |
11341 | 11352 |
11342 case Translation::INT32_STACK_SLOT: { | 11353 case Translation::INT32_STACK_SLOT: { |
11343 int input_slot_index = iterator.Next(); | 11354 int input_slot_index = iterator.Next(); |
11344 PrintF(out, "{input=%d}", input_slot_index); | 11355 os << "{input=" << input_slot_index << "}"; |
11345 break; | 11356 break; |
11346 } | 11357 } |
11347 | 11358 |
11348 case Translation::UINT32_STACK_SLOT: { | 11359 case Translation::UINT32_STACK_SLOT: { |
11349 int input_slot_index = iterator.Next(); | 11360 int input_slot_index = iterator.Next(); |
11350 PrintF(out, "{input=%d (unsigned)}", input_slot_index); | 11361 os << "{input=" << input_slot_index << " (unsigned)}"; |
11351 break; | 11362 break; |
11352 } | 11363 } |
11353 | 11364 |
11354 case Translation::DOUBLE_STACK_SLOT: { | 11365 case Translation::DOUBLE_STACK_SLOT: { |
11355 int input_slot_index = iterator.Next(); | 11366 int input_slot_index = iterator.Next(); |
11356 PrintF(out, "{input=%d}", input_slot_index); | 11367 os << "{input=" << input_slot_index << "}"; |
11357 break; | 11368 break; |
11358 } | 11369 } |
11359 | 11370 |
11360 case Translation::LITERAL: { | 11371 case Translation::LITERAL: { |
11361 unsigned literal_index = iterator.Next(); | 11372 unsigned literal_index = iterator.Next(); |
11362 PrintF(out, "{literal_id=%u}", literal_index); | 11373 os << "{literal_id=" << literal_index << "}"; |
11363 break; | 11374 break; |
11364 } | 11375 } |
11365 | 11376 |
11366 case Translation::DUPLICATED_OBJECT: { | 11377 case Translation::DUPLICATED_OBJECT: { |
11367 int object_index = iterator.Next(); | 11378 int object_index = iterator.Next(); |
11368 PrintF(out, "{object_index=%d}", object_index); | 11379 os << "{object_index=" << object_index << "}"; |
11369 break; | 11380 break; |
11370 } | 11381 } |
11371 | 11382 |
11372 case Translation::ARGUMENTS_OBJECT: | 11383 case Translation::ARGUMENTS_OBJECT: |
11373 case Translation::CAPTURED_OBJECT: { | 11384 case Translation::CAPTURED_OBJECT: { |
11374 int args_length = iterator.Next(); | 11385 int args_length = iterator.Next(); |
11375 PrintF(out, "{length=%d}", args_length); | 11386 os << "{length=" << args_length << "}"; |
11376 break; | 11387 break; |
11377 } | 11388 } |
11378 } | 11389 } |
11379 PrintF(out, "\n"); | 11390 os << "\n"; |
11380 } | 11391 } |
11381 } | 11392 } |
11382 } | 11393 } |
11383 | 11394 |
11384 | 11395 |
11385 void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) { | 11396 void DeoptimizationOutputData::DeoptimizationOutputDataPrint( |
11386 PrintF(out, "Deoptimization Output Data (deopt points = %d)\n", | 11397 OStream& os) { // NOLINT |
11387 this->DeoptPoints()); | 11398 os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints() |
| 11399 << ")\n"; |
11388 if (this->DeoptPoints() == 0) return; | 11400 if (this->DeoptPoints() == 0) return; |
11389 | 11401 |
11390 PrintF(out, "%6s %8s %s\n", "ast id", "pc", "state"); | 11402 os << "ast id pc state\n"; |
11391 for (int i = 0; i < this->DeoptPoints(); i++) { | 11403 for (int i = 0; i < this->DeoptPoints(); i++) { |
11392 int pc_and_state = this->PcAndState(i)->value(); | 11404 int pc_and_state = this->PcAndState(i)->value(); |
11393 PrintF(out, "%6d %8d %s\n", | 11405 // TODO(svenpanne) Add some basic formatting to our streams. |
11394 this->AstId(i).ToInt(), | 11406 Vector<char> buf = Vector<char>::New(100); |
11395 FullCodeGenerator::PcField::decode(pc_and_state), | 11407 SNPrintF(buf, "%6d %8d %s\n", this->AstId(i).ToInt(), |
11396 FullCodeGenerator::State2String( | 11408 FullCodeGenerator::PcField::decode(pc_and_state), |
11397 FullCodeGenerator::StateField::decode(pc_and_state))); | 11409 FullCodeGenerator::State2String( |
| 11410 FullCodeGenerator::StateField::decode(pc_and_state))); |
| 11411 os << buf.start(); |
11398 } | 11412 } |
11399 } | 11413 } |
11400 | 11414 |
11401 | 11415 |
11402 const char* Code::ICState2String(InlineCacheState state) { | 11416 const char* Code::ICState2String(InlineCacheState state) { |
11403 switch (state) { | 11417 switch (state) { |
11404 case UNINITIALIZED: return "UNINITIALIZED"; | 11418 case UNINITIALIZED: return "UNINITIALIZED"; |
11405 case PREMONOMORPHIC: return "PREMONOMORPHIC"; | 11419 case PREMONOMORPHIC: return "PREMONOMORPHIC"; |
11406 case MONOMORPHIC: return "MONOMORPHIC"; | 11420 case MONOMORPHIC: return "MONOMORPHIC"; |
11407 case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE"; | 11421 case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE"; |
(...skipping 10 matching lines...) Expand all Loading... |
11418 const char* Code::StubType2String(StubType type) { | 11432 const char* Code::StubType2String(StubType type) { |
11419 switch (type) { | 11433 switch (type) { |
11420 case NORMAL: return "NORMAL"; | 11434 case NORMAL: return "NORMAL"; |
11421 case FAST: return "FAST"; | 11435 case FAST: return "FAST"; |
11422 } | 11436 } |
11423 UNREACHABLE(); // keep the compiler happy | 11437 UNREACHABLE(); // keep the compiler happy |
11424 return NULL; | 11438 return NULL; |
11425 } | 11439 } |
11426 | 11440 |
11427 | 11441 |
11428 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { | 11442 void Code::PrintExtraICState(OStream& os, // NOLINT |
11429 PrintF(out, "extra_ic_state = "); | 11443 Kind kind, ExtraICState extra) { |
11430 const char* name = NULL; | 11444 os << "extra_ic_state = "; |
11431 switch (kind) { | 11445 if ((kind == STORE_IC || kind == KEYED_STORE_IC) && (extra == STRICT)) { |
11432 case STORE_IC: | 11446 os << "STRICT\n"; |
11433 case KEYED_STORE_IC: | |
11434 if (extra == STRICT) name = "STRICT"; | |
11435 break; | |
11436 default: | |
11437 break; | |
11438 } | |
11439 if (name != NULL) { | |
11440 PrintF(out, "%s\n", name); | |
11441 } else { | 11447 } else { |
11442 PrintF(out, "%d\n", extra); | 11448 os << extra << "\n"; |
11443 } | 11449 } |
11444 } | 11450 } |
11445 | 11451 |
11446 | 11452 |
11447 void Code::Disassemble(const char* name, FILE* out) { | 11453 void Code::Disassemble(const char* name, OStream& os) { // NOLINT |
11448 PrintF(out, "kind = %s\n", Kind2String(kind())); | 11454 os << "kind = " << Kind2String(kind()) << "\n"; |
11449 if (has_major_key()) { | 11455 if (has_major_key()) { |
11450 PrintF(out, "major_key = %s\n", | 11456 const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true); |
11451 CodeStub::MajorName(CodeStub::GetMajorKey(this), true)); | 11457 os << "major_key = " << (n == NULL ? "null" : n) << "\n"; |
11452 } | 11458 } |
11453 if (is_inline_cache_stub()) { | 11459 if (is_inline_cache_stub()) { |
11454 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); | 11460 os << "ic_state = " << ICState2String(ic_state()) << "\n"; |
11455 PrintExtraICState(out, kind(), extra_ic_state()); | 11461 PrintExtraICState(os, kind(), extra_ic_state()); |
11456 if (ic_state() == MONOMORPHIC) { | 11462 if (ic_state() == MONOMORPHIC) { |
11457 PrintF(out, "type = %s\n", StubType2String(type())); | 11463 os << "type = " << StubType2String(type()) << "\n"; |
11458 } | 11464 } |
11459 if (is_compare_ic_stub()) { | 11465 if (is_compare_ic_stub()) { |
11460 ASSERT(major_key() == CodeStub::CompareIC); | 11466 ASSERT(major_key() == CodeStub::CompareIC); |
11461 CompareIC::State left_state, right_state, handler_state; | 11467 CompareIC::State left_state, right_state, handler_state; |
11462 Token::Value op; | 11468 Token::Value op; |
11463 ICCompareStub::DecodeMinorKey(stub_info(), &left_state, &right_state, | 11469 ICCompareStub::DecodeMinorKey(stub_info(), &left_state, &right_state, |
11464 &handler_state, &op); | 11470 &handler_state, &op); |
11465 PrintF(out, "compare_state = %s*%s -> %s\n", | 11471 os << "compare_state = " << CompareIC::GetStateName(left_state) << "*" |
11466 CompareIC::GetStateName(left_state), | 11472 << CompareIC::GetStateName(right_state) << " -> " |
11467 CompareIC::GetStateName(right_state), | 11473 << CompareIC::GetStateName(handler_state) << "\n"; |
11468 CompareIC::GetStateName(handler_state)); | 11474 os << "compare_operation = " << Token::Name(op) << "\n"; |
11469 PrintF(out, "compare_operation = %s\n", Token::Name(op)); | |
11470 } | 11475 } |
11471 } | 11476 } |
11472 if ((name != NULL) && (name[0] != '\0')) { | 11477 if ((name != NULL) && (name[0] != '\0')) { |
11473 PrintF(out, "name = %s\n", name); | 11478 os << "name = " << name << "\n"; |
11474 } | 11479 } |
11475 if (kind() == OPTIMIZED_FUNCTION) { | 11480 if (kind() == OPTIMIZED_FUNCTION) { |
11476 PrintF(out, "stack_slots = %d\n", stack_slots()); | 11481 os << "stack_slots = " << stack_slots() << "\n"; |
11477 } | 11482 } |
11478 | 11483 |
11479 PrintF(out, "Instructions (size = %d)\n", instruction_size()); | 11484 os << "Instructions (size = " << instruction_size() << ")\n"; |
11480 Disassembler::Decode(out, this); | 11485 // TODO(svenpanne) The Disassembler should use streams, too! |
11481 PrintF(out, "\n"); | 11486 Disassembler::Decode(stdout, this); |
| 11487 os << "\n"; |
11482 | 11488 |
11483 if (kind() == FUNCTION) { | 11489 if (kind() == FUNCTION) { |
11484 DeoptimizationOutputData* data = | 11490 DeoptimizationOutputData* data = |
11485 DeoptimizationOutputData::cast(this->deoptimization_data()); | 11491 DeoptimizationOutputData::cast(this->deoptimization_data()); |
11486 data->DeoptimizationOutputDataPrint(out); | 11492 data->DeoptimizationOutputDataPrint(os); |
11487 } else if (kind() == OPTIMIZED_FUNCTION) { | 11493 } else if (kind() == OPTIMIZED_FUNCTION) { |
11488 DeoptimizationInputData* data = | 11494 DeoptimizationInputData* data = |
11489 DeoptimizationInputData::cast(this->deoptimization_data()); | 11495 DeoptimizationInputData::cast(this->deoptimization_data()); |
11490 data->DeoptimizationInputDataPrint(out); | 11496 data->DeoptimizationInputDataPrint(os); |
11491 } | 11497 } |
11492 PrintF(out, "\n"); | 11498 os << "\n"; |
11493 | 11499 |
11494 if (is_crankshafted()) { | 11500 if (is_crankshafted()) { |
11495 SafepointTable table(this); | 11501 SafepointTable table(this); |
11496 PrintF(out, "Safepoints (size = %u)\n", table.size()); | 11502 os << "Safepoints (size = " << table.size() << ")\n"; |
11497 for (unsigned i = 0; i < table.length(); i++) { | 11503 for (unsigned i = 0; i < table.length(); i++) { |
11498 unsigned pc_offset = table.GetPcOffset(i); | 11504 unsigned pc_offset = table.GetPcOffset(i); |
11499 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset); | 11505 os << (instruction_start() + pc_offset) << " "; |
11500 table.PrintEntry(i, out); | 11506 // TODO(svenpanne) Add some basic formatting to our streams. |
11501 PrintF(out, " (sp -> fp)"); | 11507 Vector<char> buf1 = Vector<char>::New(30); |
| 11508 SNPrintF(buf1, "%4d", pc_offset); |
| 11509 os << buf1.start() << " "; |
| 11510 table.PrintEntry(i, os); |
| 11511 os << " (sp -> fp) "; |
11502 SafepointEntry entry = table.GetEntry(i); | 11512 SafepointEntry entry = table.GetEntry(i); |
11503 if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) { | 11513 if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) { |
11504 PrintF(out, " %6d", entry.deoptimization_index()); | 11514 Vector<char> buf2 = Vector<char>::New(30); |
| 11515 SNPrintF(buf2, "%6d", entry.deoptimization_index()); |
| 11516 os << buf2.start(); |
11505 } else { | 11517 } else { |
11506 PrintF(out, " <none>"); | 11518 os << "<none>"; |
11507 } | 11519 } |
11508 if (entry.argument_count() > 0) { | 11520 if (entry.argument_count() > 0) { |
11509 PrintF(out, " argc: %d", entry.argument_count()); | 11521 os << " argc: " << entry.argument_count(); |
11510 } | 11522 } |
11511 PrintF(out, "\n"); | 11523 os << "\n"; |
11512 } | 11524 } |
11513 PrintF(out, "\n"); | 11525 os << "\n"; |
11514 } else if (kind() == FUNCTION) { | 11526 } else if (kind() == FUNCTION) { |
11515 unsigned offset = back_edge_table_offset(); | 11527 unsigned offset = back_edge_table_offset(); |
11516 // If there is no back edge table, the "table start" will be at or after | 11528 // If there is no back edge table, the "table start" will be at or after |
11517 // (due to alignment) the end of the instruction stream. | 11529 // (due to alignment) the end of the instruction stream. |
11518 if (static_cast<int>(offset) < instruction_size()) { | 11530 if (static_cast<int>(offset) < instruction_size()) { |
11519 DisallowHeapAllocation no_gc; | 11531 DisallowHeapAllocation no_gc; |
11520 BackEdgeTable back_edges(this, &no_gc); | 11532 BackEdgeTable back_edges(this, &no_gc); |
11521 | 11533 |
11522 PrintF(out, "Back edges (size = %u)\n", back_edges.length()); | 11534 os << "Back edges (size = " << back_edges.length() << ")\n"; |
11523 PrintF(out, "ast_id pc_offset loop_depth\n"); | 11535 os << "ast_id pc_offset loop_depth\n"; |
11524 | 11536 |
11525 for (uint32_t i = 0; i < back_edges.length(); i++) { | 11537 for (uint32_t i = 0; i < back_edges.length(); i++) { |
11526 PrintF(out, "%6d %9u %10u\n", back_edges.ast_id(i).ToInt(), | 11538 Vector<char> buf = Vector<char>::New(100); |
11527 back_edges.pc_offset(i), | 11539 SNPrintF(buf, "%6d %9u %10u\n", back_edges.ast_id(i).ToInt(), |
11528 back_edges.loop_depth(i)); | 11540 back_edges.pc_offset(i), back_edges.loop_depth(i)); |
| 11541 os << buf.start(); |
11529 } | 11542 } |
11530 | 11543 |
11531 PrintF(out, "\n"); | 11544 os << "\n"; |
11532 } | 11545 } |
11533 #ifdef OBJECT_PRINT | 11546 #ifdef OBJECT_PRINT |
11534 if (!type_feedback_info()->IsUndefined()) { | 11547 if (!type_feedback_info()->IsUndefined()) { |
11535 TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(out); | 11548 OFStream os(stdout); |
11536 PrintF(out, "\n"); | 11549 TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(os); |
| 11550 os << "\n"; |
11537 } | 11551 } |
11538 #endif | 11552 #endif |
11539 } | 11553 } |
11540 | 11554 |
11541 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); | 11555 os << "RelocInfo (size = " << relocation_size() << ")\n"; |
11542 for (RelocIterator it(this); !it.done(); it.next()) { | 11556 for (RelocIterator it(this); !it.done(); it.next()) { |
11543 it.rinfo()->Print(GetIsolate(), out); | 11557 it.rinfo()->Print(GetIsolate(), os); |
11544 } | 11558 } |
11545 PrintF(out, "\n"); | 11559 os << "\n"; |
11546 } | 11560 } |
11547 #endif // ENABLE_DISASSEMBLER | 11561 #endif // ENABLE_DISASSEMBLER |
11548 | 11562 |
11549 | 11563 |
11550 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( | 11564 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( |
11551 Handle<JSObject> object, | 11565 Handle<JSObject> object, |
11552 int capacity, | 11566 int capacity, |
11553 int length, | 11567 int length, |
11554 SetFastElementsCapacitySmiMode smi_mode) { | 11568 SetFastElementsCapacitySmiMode smi_mode) { |
11555 // We should never end in here with a pixel or external array. | 11569 // We should never end in here with a pixel or external array. |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12708 | 12722 |
12709 if (should_convert_to_fast_double_elements) { | 12723 if (should_convert_to_fast_double_elements) { |
12710 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); | 12724 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); |
12711 } else { | 12725 } else { |
12712 SetFastElementsCapacityAndLength(object, new_length, new_length, | 12726 SetFastElementsCapacityAndLength(object, new_length, new_length, |
12713 smi_mode); | 12727 smi_mode); |
12714 } | 12728 } |
12715 JSObject::ValidateElements(object); | 12729 JSObject::ValidateElements(object); |
12716 #ifdef DEBUG | 12730 #ifdef DEBUG |
12717 if (FLAG_trace_normalization) { | 12731 if (FLAG_trace_normalization) { |
12718 PrintF("Object elements are fast case again:\n"); | 12732 OFStream os(stdout); |
12719 object->Print(); | 12733 os << "Object elements are fast case again:\n"; |
| 12734 object->Print(os); |
12720 } | 12735 } |
12721 #endif | 12736 #endif |
12722 } | 12737 } |
12723 return value; | 12738 return value; |
12724 } | 12739 } |
12725 | 12740 |
12726 MaybeHandle<Object> JSObject::SetFastDoubleElement( | 12741 MaybeHandle<Object> JSObject::SetFastDoubleElement( |
12727 Handle<JSObject> object, | 12742 Handle<JSObject> object, |
12728 uint32_t index, | 12743 uint32_t index, |
12729 Handle<Object> value, | 12744 Handle<Object> value, |
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13562 } | 13577 } |
13563 } | 13578 } |
13564 | 13579 |
13565 | 13580 |
13566 // Certain compilers request function template instantiation when they | 13581 // Certain compilers request function template instantiation when they |
13567 // see the definition of the other template functions in the | 13582 // see the definition of the other template functions in the |
13568 // class. This requires us to have the template functions put | 13583 // class. This requires us to have the template functions put |
13569 // together, so even though this function belongs in objects-debug.cc, | 13584 // together, so even though this function belongs in objects-debug.cc, |
13570 // we keep it here instead to satisfy certain compilers. | 13585 // we keep it here instead to satisfy certain compilers. |
13571 #ifdef OBJECT_PRINT | 13586 #ifdef OBJECT_PRINT |
13572 template<typename Derived, typename Shape, typename Key> | 13587 template <typename Derived, typename Shape, typename Key> |
13573 void Dictionary<Derived, Shape, Key>::Print(FILE* out) { | 13588 void Dictionary<Derived, Shape, Key>::Print(OStream& os) { // NOLINT |
13574 int capacity = DerivedHashTable::Capacity(); | 13589 int capacity = DerivedHashTable::Capacity(); |
13575 for (int i = 0; i < capacity; i++) { | 13590 for (int i = 0; i < capacity; i++) { |
13576 Object* k = DerivedHashTable::KeyAt(i); | 13591 Object* k = DerivedHashTable::KeyAt(i); |
13577 if (DerivedHashTable::IsKey(k)) { | 13592 if (DerivedHashTable::IsKey(k)) { |
13578 PrintF(out, " "); | 13593 os << " "; |
13579 if (k->IsString()) { | 13594 if (k->IsString()) { |
13580 String::cast(k)->StringPrint(out); | 13595 String::cast(k)->StringPrint(os); |
13581 } else { | 13596 } else { |
13582 k->ShortPrint(out); | 13597 os << Brief(k); |
13583 } | 13598 } |
13584 PrintF(out, ": "); | 13599 os << ": " << Brief(ValueAt(i)) << "\n"; |
13585 ValueAt(i)->ShortPrint(out); | |
13586 PrintF(out, "\n"); | |
13587 } | 13600 } |
13588 } | 13601 } |
13589 } | 13602 } |
13590 #endif | 13603 #endif |
13591 | 13604 |
13592 | 13605 |
13593 template<typename Derived, typename Shape, typename Key> | 13606 template<typename Derived, typename Shape, typename Key> |
13594 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13607 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
13595 int pos = 0; | 13608 int pos = 0; |
13596 int capacity = DerivedHashTable::Capacity(); | 13609 int capacity = DerivedHashTable::Capacity(); |
(...skipping 3389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16986 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16999 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16987 static const char* error_messages_[] = { | 17000 static const char* error_messages_[] = { |
16988 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17001 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16989 }; | 17002 }; |
16990 #undef ERROR_MESSAGES_TEXTS | 17003 #undef ERROR_MESSAGES_TEXTS |
16991 return error_messages_[reason]; | 17004 return error_messages_[reason]; |
16992 } | 17005 } |
16993 | 17006 |
16994 | 17007 |
16995 } } // namespace v8::internal | 17008 } } // namespace v8::internal |
OLD | NEW |