| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 2672aac74528c43cd99c021899e93755c3be1e70..c84176b6449c1aa5a91d9836dcf5d92a618de0ef 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -963,29 +963,32 @@ bool Object::SameValueZero(Object* other) {
|
|
|
|
|
| void Object::ShortPrint(FILE* out) {
|
| - HeapStringAllocator allocator;
|
| - StringStream accumulator(&allocator);
|
| - ShortPrint(&accumulator);
|
| - accumulator.OutputToFile(out);
|
| + OFStream os(out);
|
| + os << Brief(this);
|
| }
|
|
|
|
|
| void Object::ShortPrint(StringStream* accumulator) {
|
| - if (IsSmi()) {
|
| - Smi::cast(this)->SmiPrint(accumulator);
|
| - } else {
|
| - HeapObject::cast(this)->HeapObjectShortPrint(accumulator);
|
| - }
|
| + OStringStream os;
|
| + os << Brief(this);
|
| + accumulator->Add(os.c_str());
|
| }
|
|
|
|
|
| -void Smi::SmiPrint(FILE* out) {
|
| - PrintF(out, "%d", value());
|
| +OStream& operator<<(OStream& os, const Brief& v) {
|
| + if (v.value->IsSmi()) {
|
| + Smi::cast(v.value)->SmiPrint(os);
|
| + } else {
|
| + // TODO(svenpanne) Const-correct HeapObjectShortPrint!
|
| + HeapObject* obj = const_cast<HeapObject*>(HeapObject::cast(v.value));
|
| + obj->HeapObjectShortPrint(os);
|
| + }
|
| + return os;
|
| }
|
|
|
|
|
| -void Smi::SmiPrint(StringStream* accumulator) {
|
| - accumulator->Add("%d", value());
|
| +void Smi::SmiPrint(OStream& os) const { // NOLINT
|
| + os << value();
|
| }
|
|
|
|
|
| @@ -1241,6 +1244,16 @@ void String::StringShortPrint(StringStream* accumulator) {
|
| }
|
|
|
|
|
| +void String::PrintUC16(OStream& os, int start, int end) { // NOLINT
|
| + if (end < 0) end = length();
|
| + ConsStringIteratorOp op;
|
| + StringCharacterStream stream(this, &op, start);
|
| + for (int i = start; i < end && stream.HasMore(); i++) {
|
| + os << AsUC16(stream.GetNext());
|
| + }
|
| +}
|
| +
|
| +
|
| void JSObject::JSObjectShortPrint(StringStream* accumulator) {
|
| switch (map()->instance_type()) {
|
| case JS_ARRAY_TYPE: {
|
| @@ -1344,11 +1357,9 @@ void JSObject::PrintElementsTransition(
|
| ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
|
| ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
|
| if (from_kind != to_kind) {
|
| - PrintF(file, "elements transition [");
|
| - PrintElementsKind(file, from_kind);
|
| - PrintF(file, " -> ");
|
| - PrintElementsKind(file, to_kind);
|
| - PrintF(file, "] in ");
|
| + OFStream os(file);
|
| + os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
|
| + << ElementsKindToString(to_kind) << "] in ";
|
| JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
|
| PrintF(file, " for ");
|
| object->ShortPrint(file);
|
| @@ -1432,53 +1443,59 @@ void JSObject::PrintInstanceMigration(FILE* file,
|
| }
|
|
|
|
|
| -void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
|
| +void HeapObject::HeapObjectShortPrint(OStream& os) { // NOLINT
|
| Heap* heap = GetHeap();
|
| if (!heap->Contains(this)) {
|
| - accumulator->Add("!!!INVALID POINTER!!!");
|
| + os << "!!!INVALID POINTER!!!";
|
| return;
|
| }
|
| if (!heap->Contains(map())) {
|
| - accumulator->Add("!!!INVALID MAP!!!");
|
| + os << "!!!INVALID MAP!!!";
|
| return;
|
| }
|
|
|
| - accumulator->Add("%p ", this);
|
| + os << this << " ";
|
|
|
| if (IsString()) {
|
| - String::cast(this)->StringShortPrint(accumulator);
|
| + HeapStringAllocator allocator;
|
| + StringStream accumulator(&allocator);
|
| + String::cast(this)->StringShortPrint(&accumulator);
|
| + os << accumulator.ToCString().get();
|
| return;
|
| }
|
| if (IsJSObject()) {
|
| - JSObject::cast(this)->JSObjectShortPrint(accumulator);
|
| + HeapStringAllocator allocator;
|
| + StringStream accumulator(&allocator);
|
| + JSObject::cast(this)->JSObjectShortPrint(&accumulator);
|
| + os << accumulator.ToCString().get();
|
| return;
|
| }
|
| switch (map()->instance_type()) {
|
| case MAP_TYPE:
|
| - accumulator->Add("<Map(elements=%u)>", Map::cast(this)->elements_kind());
|
| + os << "<Map(elements=" << Map::cast(this)->elements_kind() << ")>";
|
| break;
|
| case FIXED_ARRAY_TYPE:
|
| - accumulator->Add("<FixedArray[%u]>", FixedArray::cast(this)->length());
|
| + os << "<FixedArray[" << FixedArray::cast(this)->length() << "]>";
|
| break;
|
| case FIXED_DOUBLE_ARRAY_TYPE:
|
| - accumulator->Add("<FixedDoubleArray[%u]>",
|
| - FixedDoubleArray::cast(this)->length());
|
| + os << "<FixedDoubleArray[" << FixedDoubleArray::cast(this)->length()
|
| + << "]>";
|
| break;
|
| case BYTE_ARRAY_TYPE:
|
| - accumulator->Add("<ByteArray[%u]>", ByteArray::cast(this)->length());
|
| + os << "<ByteArray[" << ByteArray::cast(this)->length() << "]>";
|
| break;
|
| case FREE_SPACE_TYPE:
|
| - accumulator->Add("<FreeSpace[%u]>", FreeSpace::cast(this)->Size());
|
| - break;
|
| -#define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size) \
|
| - case EXTERNAL_##TYPE##_ARRAY_TYPE: \
|
| - accumulator->Add("<External" #Type "Array[%u]>", \
|
| - External##Type##Array::cast(this)->length()); \
|
| - break; \
|
| - case FIXED_##TYPE##_ARRAY_TYPE: \
|
| - accumulator->Add("<Fixed" #Type "Array[%u]>", \
|
| - Fixed##Type##Array::cast(this)->length()); \
|
| + os << "<FreeSpace[" << FreeSpace::cast(this)->Size() << "]>";
|
| break;
|
| +#define TYPED_ARRAY_SHORT_PRINT(Type, type, TYPE, ctype, size) \
|
| + case EXTERNAL_##TYPE##_ARRAY_TYPE: \
|
| + os << "<External" #Type "Array[" \
|
| + << External##Type##Array::cast(this)->length() << "]>"; \
|
| + break; \
|
| + case FIXED_##TYPE##_ARRAY_TYPE: \
|
| + os << "<Fixed" #Type "Array[" << Fixed##Type##Array::cast(this)->length() \
|
| + << "]>"; \
|
| + break;
|
|
|
| TYPED_ARRAYS(TYPED_ARRAY_SHORT_PRINT)
|
| #undef TYPED_ARRAY_SHORT_PRINT
|
| @@ -1488,80 +1505,92 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
|
| SmartArrayPointer<char> debug_name =
|
| shared->DebugName()->ToCString();
|
| if (debug_name[0] != 0) {
|
| - accumulator->Add("<SharedFunctionInfo %s>", debug_name.get());
|
| + os << "<SharedFunctionInfo " << debug_name.get() << ">";
|
| } else {
|
| - accumulator->Add("<SharedFunctionInfo>");
|
| + os << "<SharedFunctionInfo>";
|
| }
|
| break;
|
| }
|
| case JS_MESSAGE_OBJECT_TYPE:
|
| - accumulator->Add("<JSMessageObject>");
|
| + os << "<JSMessageObject>";
|
| break;
|
| #define MAKE_STRUCT_CASE(NAME, Name, name) \
|
| case NAME##_TYPE: \
|
| - accumulator->Put('<'); \
|
| - accumulator->Add(#Name); \
|
| - accumulator->Put('>'); \
|
| + os << "<" #Name ">"; \
|
| break;
|
| STRUCT_LIST(MAKE_STRUCT_CASE)
|
| #undef MAKE_STRUCT_CASE
|
| case CODE_TYPE:
|
| - accumulator->Add("<Code>");
|
| + os << "<Code>";
|
| break;
|
| case ODDBALL_TYPE: {
|
| - if (IsUndefined())
|
| - accumulator->Add("<undefined>");
|
| - else if (IsTheHole())
|
| - accumulator->Add("<the hole>");
|
| - else if (IsNull())
|
| - accumulator->Add("<null>");
|
| - else if (IsTrue())
|
| - accumulator->Add("<true>");
|
| - else if (IsFalse())
|
| - accumulator->Add("<false>");
|
| - else
|
| - accumulator->Add("<Odd Oddball>");
|
| + if (IsUndefined()) {
|
| + os << "<undefined>";
|
| + } else if (IsTheHole()) {
|
| + os << "<the hole>";
|
| + } else if (IsNull()) {
|
| + os << "<null>";
|
| + } else if (IsTrue()) {
|
| + os << "<true>";
|
| + } else if (IsFalse()) {
|
| + os << "<false>";
|
| + } else {
|
| + os << "<Odd Oddball>";
|
| + }
|
| break;
|
| }
|
| case SYMBOL_TYPE: {
|
| Symbol* symbol = Symbol::cast(this);
|
| - accumulator->Add("<Symbol: %d", symbol->Hash());
|
| + os << "<Symbol: " << symbol->Hash();
|
| if (!symbol->name()->IsUndefined()) {
|
| - accumulator->Add(" ");
|
| - String::cast(symbol->name())->StringShortPrint(accumulator);
|
| + os << " ";
|
| + HeapStringAllocator allocator;
|
| + StringStream accumulator(&allocator);
|
| + String::cast(symbol->name())->StringShortPrint(&accumulator);
|
| + os << accumulator.ToCString().get();
|
| }
|
| - accumulator->Add(">");
|
| + os << ">";
|
| break;
|
| }
|
| - case HEAP_NUMBER_TYPE:
|
| - accumulator->Add("<Number: ");
|
| - HeapNumber::cast(this)->HeapNumberPrint(accumulator);
|
| - accumulator->Put('>');
|
| + case HEAP_NUMBER_TYPE: {
|
| + os << "<Number: ";
|
| + HeapNumber::cast(this)->HeapNumberPrint(os);
|
| + os << ">";
|
| break;
|
| - case MUTABLE_HEAP_NUMBER_TYPE:
|
| - accumulator->Add("<MutableNumber: ");
|
| - HeapNumber::cast(this)->HeapNumberPrint(accumulator);
|
| - accumulator->Put('>');
|
| + }
|
| + case MUTABLE_HEAP_NUMBER_TYPE: {
|
| + os << "<MutableNumber: ";
|
| + HeapNumber::cast(this)->HeapNumberPrint(os);
|
| + os << '>';
|
| break;
|
| + }
|
| case JS_PROXY_TYPE:
|
| - accumulator->Add("<JSProxy>");
|
| + os << "<JSProxy>";
|
| break;
|
| case JS_FUNCTION_PROXY_TYPE:
|
| - accumulator->Add("<JSFunctionProxy>");
|
| + os << "<JSFunctionProxy>";
|
| break;
|
| case FOREIGN_TYPE:
|
| - accumulator->Add("<Foreign>");
|
| + os << "<Foreign>";
|
| break;
|
| - case CELL_TYPE:
|
| - accumulator->Add("Cell for ");
|
| - Cell::cast(this)->value()->ShortPrint(accumulator);
|
| + case CELL_TYPE: {
|
| + os << "Cell for ";
|
| + HeapStringAllocator allocator;
|
| + StringStream accumulator(&allocator);
|
| + Cell::cast(this)->value()->ShortPrint(&accumulator);
|
| + os << accumulator.ToCString().get();
|
| break;
|
| - case PROPERTY_CELL_TYPE:
|
| - accumulator->Add("PropertyCell for ");
|
| - PropertyCell::cast(this)->value()->ShortPrint(accumulator);
|
| + }
|
| + case PROPERTY_CELL_TYPE: {
|
| + os << "PropertyCell for ";
|
| + HeapStringAllocator allocator;
|
| + StringStream accumulator(&allocator);
|
| + PropertyCell::cast(this)->value()->ShortPrint(&accumulator);
|
| + os << accumulator.ToCString().get();
|
| break;
|
| + }
|
| default:
|
| - accumulator->Add("<Other heap object (%d)>", map()->instance_type());
|
| + os << "<Other heap object (" << map()->instance_type() << ")>";
|
| break;
|
| }
|
| }
|
| @@ -1709,21 +1738,8 @@ bool HeapNumber::HeapNumberBooleanValue() {
|
| }
|
|
|
|
|
| -void HeapNumber::HeapNumberPrint(FILE* out) {
|
| - PrintF(out, "%.16g", value());
|
| -}
|
| -
|
| -
|
| -void HeapNumber::HeapNumberPrint(StringStream* accumulator) {
|
| - // The Windows version of vsnprintf can allocate when printing a %g string
|
| - // into a buffer that may not be big enough. We don't want random memory
|
| - // allocation when producing post-crash stack traces, so we print into a
|
| - // buffer that is plenty big enough for any floating point number, then
|
| - // print that using vsnprintf (which may truncate but never allocate if
|
| - // there is no more space in the buffer).
|
| - EmbeddedVector<char, 100> buffer;
|
| - SNPrintF(buffer, "%.16g", value());
|
| - accumulator->Add("%s", buffer.start());
|
| +void HeapNumber::HeapNumberPrint(OStream& os) { // NOLINT
|
| + os << value();
|
| }
|
|
|
|
|
| @@ -4709,8 +4725,9 @@ void JSObject::MigrateFastToSlow(Handle<JSObject> object,
|
|
|
| #ifdef DEBUG
|
| if (FLAG_trace_normalization) {
|
| - PrintF("Object properties have been normalized:\n");
|
| - object->Print();
|
| + OFStream os(stdout);
|
| + os << "Object properties have been normalized:\n";
|
| + object->Print(os);
|
| }
|
| #endif
|
| }
|
| @@ -4938,8 +4955,9 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
|
|
|
| #ifdef DEBUG
|
| if (FLAG_trace_normalization) {
|
| - PrintF("Object elements have been normalized:\n");
|
| - object->Print();
|
| + OFStream os(stdout);
|
| + os << "Object elements have been normalized:\n";
|
| + object->Print(os);
|
| }
|
| #endif
|
|
|
| @@ -10370,7 +10388,7 @@ String* SharedFunctionInfo::DebugName() {
|
| }
|
|
|
|
|
| -bool SharedFunctionInfo::HasSourceCode() {
|
| +bool SharedFunctionInfo::HasSourceCode() const {
|
| return !script()->IsUndefined() &&
|
| !reinterpret_cast<Script*>(script())->source()->IsUndefined();
|
| }
|
| @@ -10415,43 +10433,36 @@ int SharedFunctionInfo::CalculateInObjectProperties() {
|
| }
|
|
|
|
|
| -// Support function for printing the source code to a StringStream
|
| -// without any allocation in the heap.
|
| -void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
|
| - int max_length) {
|
| +// Output the source code without any allocation in the heap.
|
| +OStream& operator<<(OStream& os, const SourceCodeOf& v) {
|
| + const SharedFunctionInfo* s = v.value;
|
| // For some native functions there is no source.
|
| - if (!HasSourceCode()) {
|
| - accumulator->Add("<No Source>");
|
| - return;
|
| - }
|
| + if (!s->HasSourceCode()) return os << "<No Source>";
|
|
|
| // Get the source for the script which this function came from.
|
| // Don't use String::cast because we don't want more assertion errors while
|
| // we are already creating a stack dump.
|
| String* script_source =
|
| - reinterpret_cast<String*>(Script::cast(script())->source());
|
| + reinterpret_cast<String*>(Script::cast(s->script())->source());
|
|
|
| - if (!script_source->LooksValid()) {
|
| - accumulator->Add("<Invalid Source>");
|
| - return;
|
| - }
|
| + if (!script_source->LooksValid()) return os << "<Invalid Source>";
|
|
|
| - if (!is_toplevel()) {
|
| - accumulator->Add("function ");
|
| - Object* name = this->name();
|
| + if (!s->is_toplevel()) {
|
| + os << "function ";
|
| + Object* name = s->name();
|
| if (name->IsString() && String::cast(name)->length() > 0) {
|
| - accumulator->PrintName(name);
|
| + String::cast(name)->PrintUC16(os);
|
| }
|
| }
|
|
|
| - int len = end_position() - start_position();
|
| - if (len <= max_length || max_length < 0) {
|
| - accumulator->Put(script_source, start_position(), end_position());
|
| + int len = s->end_position() - s->start_position();
|
| + if (len <= v.max_length || v.max_length < 0) {
|
| + script_source->PrintUC16(os, s->start_position(), s->end_position());
|
| + return os;
|
| } else {
|
| - accumulator->Put(script_source,
|
| - start_position(),
|
| - start_position() + max_length);
|
| - accumulator->Add("...\n");
|
| + script_source->PrintUC16(os, s->start_position(),
|
| + s->start_position() + v.max_length);
|
| + return os << "...\n";
|
| }
|
| }
|
|
|
| @@ -11221,23 +11232,25 @@ const char* Code::Kind2String(Kind kind) {
|
|
|
| #ifdef ENABLE_DISASSEMBLER
|
|
|
| -void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
|
| +void DeoptimizationInputData::DeoptimizationInputDataPrint(
|
| + OStream& os) { // NOLINT
|
| disasm::NameConverter converter;
|
| int deopt_count = DeoptCount();
|
| - PrintF(out, "Deoptimization Input Data (deopt points = %d)\n", deopt_count);
|
| + os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
|
| if (0 == deopt_count) return;
|
|
|
| - PrintF(out, "%6s %6s %6s %6s %12s\n", "index", "ast id", "argc", "pc",
|
| - FLAG_print_code_verbose ? "commands" : "");
|
| + os << " index ast id argc pc";
|
| + if (FLAG_print_code_verbose) os << "commands";
|
| + os << "\n";
|
| for (int i = 0; i < deopt_count; i++) {
|
| - PrintF(out, "%6d %6d %6d %6d",
|
| - i,
|
| - AstId(i).ToInt(),
|
| - ArgumentsStackHeight(i)->value(),
|
| - Pc(i)->value());
|
| + // TODO(svenpanne) Add some basic formatting to our streams.
|
| + Vector<char> buf1 = Vector<char>::New(128);
|
| + SNPrintF(buf1, "%6d %6d %6d %6d", i, AstId(i).ToInt(),
|
| + ArgumentsStackHeight(i)->value(), Pc(i)->value());
|
| + os << buf1.start();
|
|
|
| if (!FLAG_print_code_verbose) {
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
| continue;
|
| }
|
| // Print details of the frame translation.
|
| @@ -11248,15 +11261,16 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
|
| ASSERT(Translation::BEGIN == opcode);
|
| int frame_count = iterator.Next();
|
| int jsframe_count = iterator.Next();
|
| - PrintF(out, " %s {frame count=%d, js frame count=%d}\n",
|
| - Translation::StringFor(opcode),
|
| - frame_count,
|
| - jsframe_count);
|
| + os << " " << Translation::StringFor(opcode)
|
| + << " {frame count=" << frame_count
|
| + << ", js frame count=" << jsframe_count << "}\n";
|
|
|
| while (iterator.HasNext() &&
|
| Translation::BEGIN !=
|
| (opcode = static_cast<Translation::Opcode>(iterator.Next()))) {
|
| - PrintF(out, "%24s %s ", "", Translation::StringFor(opcode));
|
| + Vector<char> buf2 = Vector<char>::New(128);
|
| + SNPrintF(buf2, "%24s %s ", "", Translation::StringFor(opcode));
|
| + os << buf2.start();
|
|
|
| switch (opcode) {
|
| case Translation::BEGIN:
|
| @@ -11267,20 +11281,20 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
|
| int ast_id = iterator.Next();
|
| int function_id = iterator.Next();
|
| unsigned height = iterator.Next();
|
| - PrintF(out, "{ast_id=%d, function=", ast_id);
|
| + os << "{ast_id=" << ast_id << ", function=";
|
| if (function_id != Translation::kSelfLiteralId) {
|
| Object* function = LiteralArray()->get(function_id);
|
| - JSFunction::cast(function)->PrintName(out);
|
| + os << Brief(JSFunction::cast(function)->shared()->DebugName());
|
| } else {
|
| - PrintF(out, "<self>");
|
| + os << "<self>";
|
| }
|
| - PrintF(out, ", height=%u}", height);
|
| + os << ", height=" << height << "}";
|
| break;
|
| }
|
|
|
| case Translation::COMPILED_STUB_FRAME: {
|
| Code::Kind stub_kind = static_cast<Code::Kind>(iterator.Next());
|
| - PrintF(out, "{kind=%d}", stub_kind);
|
| + os << "{kind=" << stub_kind << "}";
|
| break;
|
| }
|
|
|
| @@ -11290,9 +11304,8 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
|
| JSFunction* function =
|
| JSFunction::cast(LiteralArray()->get(function_id));
|
| unsigned height = iterator.Next();
|
| - PrintF(out, "{function=");
|
| - function->PrintName(out);
|
| - PrintF(out, ", height=%u}", height);
|
| + os << "{function=" << Brief(function->shared()->DebugName())
|
| + << ", height=" << height << "}";
|
| break;
|
| }
|
|
|
| @@ -11301,100 +11314,101 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
|
| int function_id = iterator.Next();
|
| JSFunction* function =
|
| JSFunction::cast(LiteralArray()->get(function_id));
|
| - PrintF(out, "{function=");
|
| - function->PrintName(out);
|
| - PrintF(out, "}");
|
| + os << "{function=" << Brief(function->shared()->DebugName()) << "}";
|
| break;
|
| }
|
|
|
| case Translation::REGISTER: {
|
| int reg_code = iterator.Next();
|
| - PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code));
|
| + os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
|
| break;
|
| }
|
|
|
| case Translation::INT32_REGISTER: {
|
| int reg_code = iterator.Next();
|
| - PrintF(out, "{input=%s}", converter.NameOfCPURegister(reg_code));
|
| + os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
|
| break;
|
| }
|
|
|
| case Translation::UINT32_REGISTER: {
|
| int reg_code = iterator.Next();
|
| - PrintF(out, "{input=%s (unsigned)}",
|
| - converter.NameOfCPURegister(reg_code));
|
| + os << "{input=" << converter.NameOfCPURegister(reg_code)
|
| + << " (unsigned)}";
|
| break;
|
| }
|
|
|
| case Translation::DOUBLE_REGISTER: {
|
| int reg_code = iterator.Next();
|
| - PrintF(out, "{input=%s}",
|
| - DoubleRegister::AllocationIndexToString(reg_code));
|
| + os << "{input=" << DoubleRegister::AllocationIndexToString(reg_code)
|
| + << "}";
|
| break;
|
| }
|
|
|
| case Translation::STACK_SLOT: {
|
| int input_slot_index = iterator.Next();
|
| - PrintF(out, "{input=%d}", input_slot_index);
|
| + os << "{input=" << input_slot_index << "}";
|
| break;
|
| }
|
|
|
| case Translation::INT32_STACK_SLOT: {
|
| int input_slot_index = iterator.Next();
|
| - PrintF(out, "{input=%d}", input_slot_index);
|
| + os << "{input=" << input_slot_index << "}";
|
| break;
|
| }
|
|
|
| case Translation::UINT32_STACK_SLOT: {
|
| int input_slot_index = iterator.Next();
|
| - PrintF(out, "{input=%d (unsigned)}", input_slot_index);
|
| + os << "{input=" << input_slot_index << " (unsigned)}";
|
| break;
|
| }
|
|
|
| case Translation::DOUBLE_STACK_SLOT: {
|
| int input_slot_index = iterator.Next();
|
| - PrintF(out, "{input=%d}", input_slot_index);
|
| + os << "{input=" << input_slot_index << "}";
|
| break;
|
| }
|
|
|
| case Translation::LITERAL: {
|
| unsigned literal_index = iterator.Next();
|
| - PrintF(out, "{literal_id=%u}", literal_index);
|
| + os << "{literal_id=" << literal_index << "}";
|
| break;
|
| }
|
|
|
| case Translation::DUPLICATED_OBJECT: {
|
| int object_index = iterator.Next();
|
| - PrintF(out, "{object_index=%d}", object_index);
|
| + os << "{object_index=" << object_index << "}";
|
| break;
|
| }
|
|
|
| case Translation::ARGUMENTS_OBJECT:
|
| case Translation::CAPTURED_OBJECT: {
|
| int args_length = iterator.Next();
|
| - PrintF(out, "{length=%d}", args_length);
|
| + os << "{length=" << args_length << "}";
|
| break;
|
| }
|
| }
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
| }
|
| }
|
| }
|
|
|
|
|
| -void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) {
|
| - PrintF(out, "Deoptimization Output Data (deopt points = %d)\n",
|
| - this->DeoptPoints());
|
| +void DeoptimizationOutputData::DeoptimizationOutputDataPrint(
|
| + OStream& os) { // NOLINT
|
| + os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints()
|
| + << ")\n";
|
| if (this->DeoptPoints() == 0) return;
|
|
|
| - PrintF(out, "%6s %8s %s\n", "ast id", "pc", "state");
|
| + os << "ast id pc state\n";
|
| for (int i = 0; i < this->DeoptPoints(); i++) {
|
| int pc_and_state = this->PcAndState(i)->value();
|
| - PrintF(out, "%6d %8d %s\n",
|
| - this->AstId(i).ToInt(),
|
| - FullCodeGenerator::PcField::decode(pc_and_state),
|
| - FullCodeGenerator::State2String(
|
| - FullCodeGenerator::StateField::decode(pc_and_state)));
|
| + // TODO(svenpanne) Add some basic formatting to our streams.
|
| + Vector<char> buf = Vector<char>::New(100);
|
| + SNPrintF(buf, "%6d %8d %s\n", this->AstId(i).ToInt(),
|
| + FullCodeGenerator::PcField::decode(pc_and_state),
|
| + FullCodeGenerator::State2String(
|
| + FullCodeGenerator::StateField::decode(pc_and_state)));
|
| + os << buf.start();
|
| }
|
| }
|
|
|
| @@ -11425,36 +11439,28 @@ const char* Code::StubType2String(StubType type) {
|
| }
|
|
|
|
|
| -void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
|
| - PrintF(out, "extra_ic_state = ");
|
| - const char* name = NULL;
|
| - switch (kind) {
|
| - case STORE_IC:
|
| - case KEYED_STORE_IC:
|
| - if (extra == STRICT) name = "STRICT";
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - if (name != NULL) {
|
| - PrintF(out, "%s\n", name);
|
| +void Code::PrintExtraICState(OStream& os, // NOLINT
|
| + Kind kind, ExtraICState extra) {
|
| + os << "extra_ic_state = ";
|
| + if ((kind == STORE_IC || kind == KEYED_STORE_IC) && (extra == STRICT)) {
|
| + os << "STRICT\n";
|
| } else {
|
| - PrintF(out, "%d\n", extra);
|
| + os << extra << "\n";
|
| }
|
| }
|
|
|
|
|
| -void Code::Disassemble(const char* name, FILE* out) {
|
| - PrintF(out, "kind = %s\n", Kind2String(kind()));
|
| +void Code::Disassemble(const char* name, OStream& os) { // NOLINT
|
| + os << "kind = " << Kind2String(kind()) << "\n";
|
| if (has_major_key()) {
|
| - PrintF(out, "major_key = %s\n",
|
| - CodeStub::MajorName(CodeStub::GetMajorKey(this), true));
|
| + const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true);
|
| + os << "major_key = " << (n == NULL ? "null" : n) << "\n";
|
| }
|
| if (is_inline_cache_stub()) {
|
| - PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
|
| - PrintExtraICState(out, kind(), extra_ic_state());
|
| + os << "ic_state = " << ICState2String(ic_state()) << "\n";
|
| + PrintExtraICState(os, kind(), extra_ic_state());
|
| if (ic_state() == MONOMORPHIC) {
|
| - PrintF(out, "type = %s\n", StubType2String(type()));
|
| + os << "type = " << StubType2String(type()) << "\n";
|
| }
|
| if (is_compare_ic_stub()) {
|
| ASSERT(major_key() == CodeStub::CompareIC);
|
| @@ -11462,55 +11468,61 @@ void Code::Disassemble(const char* name, FILE* out) {
|
| Token::Value op;
|
| ICCompareStub::DecodeMinorKey(stub_info(), &left_state, &right_state,
|
| &handler_state, &op);
|
| - PrintF(out, "compare_state = %s*%s -> %s\n",
|
| - CompareIC::GetStateName(left_state),
|
| - CompareIC::GetStateName(right_state),
|
| - CompareIC::GetStateName(handler_state));
|
| - PrintF(out, "compare_operation = %s\n", Token::Name(op));
|
| + os << "compare_state = " << CompareIC::GetStateName(left_state) << "*"
|
| + << CompareIC::GetStateName(right_state) << " -> "
|
| + << CompareIC::GetStateName(handler_state) << "\n";
|
| + os << "compare_operation = " << Token::Name(op) << "\n";
|
| }
|
| }
|
| if ((name != NULL) && (name[0] != '\0')) {
|
| - PrintF(out, "name = %s\n", name);
|
| + os << "name = " << name << "\n";
|
| }
|
| if (kind() == OPTIMIZED_FUNCTION) {
|
| - PrintF(out, "stack_slots = %d\n", stack_slots());
|
| + os << "stack_slots = " << stack_slots() << "\n";
|
| }
|
|
|
| - PrintF(out, "Instructions (size = %d)\n", instruction_size());
|
| - Disassembler::Decode(out, this);
|
| - PrintF(out, "\n");
|
| + os << "Instructions (size = " << instruction_size() << ")\n";
|
| + // TODO(svenpanne) The Disassembler should use streams, too!
|
| + Disassembler::Decode(stdout, this);
|
| + os << "\n";
|
|
|
| if (kind() == FUNCTION) {
|
| DeoptimizationOutputData* data =
|
| DeoptimizationOutputData::cast(this->deoptimization_data());
|
| - data->DeoptimizationOutputDataPrint(out);
|
| + data->DeoptimizationOutputDataPrint(os);
|
| } else if (kind() == OPTIMIZED_FUNCTION) {
|
| DeoptimizationInputData* data =
|
| DeoptimizationInputData::cast(this->deoptimization_data());
|
| - data->DeoptimizationInputDataPrint(out);
|
| + data->DeoptimizationInputDataPrint(os);
|
| }
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
|
|
| if (is_crankshafted()) {
|
| SafepointTable table(this);
|
| - PrintF(out, "Safepoints (size = %u)\n", table.size());
|
| + os << "Safepoints (size = " << table.size() << ")\n";
|
| for (unsigned i = 0; i < table.length(); i++) {
|
| unsigned pc_offset = table.GetPcOffset(i);
|
| - PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset);
|
| - table.PrintEntry(i, out);
|
| - PrintF(out, " (sp -> fp)");
|
| + os << (instruction_start() + pc_offset) << " ";
|
| + // TODO(svenpanne) Add some basic formatting to our streams.
|
| + Vector<char> buf1 = Vector<char>::New(30);
|
| + SNPrintF(buf1, "%4d", pc_offset);
|
| + os << buf1.start() << " ";
|
| + table.PrintEntry(i, os);
|
| + os << " (sp -> fp) ";
|
| SafepointEntry entry = table.GetEntry(i);
|
| if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
|
| - PrintF(out, " %6d", entry.deoptimization_index());
|
| + Vector<char> buf2 = Vector<char>::New(30);
|
| + SNPrintF(buf2, "%6d", entry.deoptimization_index());
|
| + os << buf2.start();
|
| } else {
|
| - PrintF(out, " <none>");
|
| + os << "<none>";
|
| }
|
| if (entry.argument_count() > 0) {
|
| - PrintF(out, " argc: %d", entry.argument_count());
|
| + os << " argc: " << entry.argument_count();
|
| }
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
| }
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
| } else if (kind() == FUNCTION) {
|
| unsigned offset = back_edge_table_offset();
|
| // If there is no back edge table, the "table start" will be at or after
|
| @@ -11519,30 +11531,32 @@ void Code::Disassemble(const char* name, FILE* out) {
|
| DisallowHeapAllocation no_gc;
|
| BackEdgeTable back_edges(this, &no_gc);
|
|
|
| - PrintF(out, "Back edges (size = %u)\n", back_edges.length());
|
| - PrintF(out, "ast_id pc_offset loop_depth\n");
|
| + os << "Back edges (size = " << back_edges.length() << ")\n";
|
| + os << "ast_id pc_offset loop_depth\n";
|
|
|
| for (uint32_t i = 0; i < back_edges.length(); i++) {
|
| - PrintF(out, "%6d %9u %10u\n", back_edges.ast_id(i).ToInt(),
|
| - back_edges.pc_offset(i),
|
| - back_edges.loop_depth(i));
|
| + Vector<char> buf = Vector<char>::New(100);
|
| + SNPrintF(buf, "%6d %9u %10u\n", back_edges.ast_id(i).ToInt(),
|
| + back_edges.pc_offset(i), back_edges.loop_depth(i));
|
| + os << buf.start();
|
| }
|
|
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
| }
|
| #ifdef OBJECT_PRINT
|
| if (!type_feedback_info()->IsUndefined()) {
|
| - TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(out);
|
| - PrintF(out, "\n");
|
| + OFStream os(stdout);
|
| + TypeFeedbackInfo::cast(type_feedback_info())->TypeFeedbackInfoPrint(os);
|
| + os << "\n";
|
| }
|
| #endif
|
| }
|
|
|
| - PrintF(out, "RelocInfo (size = %d)\n", relocation_size());
|
| + os << "RelocInfo (size = " << relocation_size() << ")\n";
|
| for (RelocIterator it(this); !it.done(); it.next()) {
|
| - it.rinfo()->Print(GetIsolate(), out);
|
| + it.rinfo()->Print(GetIsolate(), os);
|
| }
|
| - PrintF(out, "\n");
|
| + os << "\n";
|
| }
|
| #endif // ENABLE_DISASSEMBLER
|
|
|
| @@ -12715,8 +12729,9 @@ MaybeHandle<Object> JSObject::SetDictionaryElement(
|
| JSObject::ValidateElements(object);
|
| #ifdef DEBUG
|
| if (FLAG_trace_normalization) {
|
| - PrintF("Object elements are fast case again:\n");
|
| - object->Print();
|
| + OFStream os(stdout);
|
| + os << "Object elements are fast case again:\n";
|
| + object->Print(os);
|
| }
|
| #endif
|
| }
|
| @@ -13569,21 +13584,19 @@ bool JSObject::ShouldConvertToFastDoubleElements(
|
| // together, so even though this function belongs in objects-debug.cc,
|
| // we keep it here instead to satisfy certain compilers.
|
| #ifdef OBJECT_PRINT
|
| -template<typename Derived, typename Shape, typename Key>
|
| -void Dictionary<Derived, Shape, Key>::Print(FILE* out) {
|
| +template <typename Derived, typename Shape, typename Key>
|
| +void Dictionary<Derived, Shape, Key>::Print(OStream& os) { // NOLINT
|
| int capacity = DerivedHashTable::Capacity();
|
| for (int i = 0; i < capacity; i++) {
|
| Object* k = DerivedHashTable::KeyAt(i);
|
| if (DerivedHashTable::IsKey(k)) {
|
| - PrintF(out, " ");
|
| + os << " ";
|
| if (k->IsString()) {
|
| - String::cast(k)->StringPrint(out);
|
| + String::cast(k)->StringPrint(os);
|
| } else {
|
| - k->ShortPrint(out);
|
| + os << Brief(k);
|
| }
|
| - PrintF(out, ": ");
|
| - ValueAt(i)->ShortPrint(out);
|
| - PrintF(out, "\n");
|
| + os << ": " << Brief(ValueAt(i)) << "\n";
|
| }
|
| }
|
| }
|
|
|