void EventGraphDisplay::outputGraph(const ActionLogPrinter* action_printer, std::string* output) { m_nodeSelection->addNode(m_focusNode, NODE_FOCUS); m_nodeSelection->addNode(0, NODE_FIRST_NODE); int node_id; while (m_nodeSelection->getNode(&node_id) && m_includedNodes.size() < 10) { if (m_graphInfo->isNodeDropped(node_id)) continue; addNode(action_printer, node_id); } for (std::set<int>::const_iterator it1 = m_includedNodes.begin(); it1 != m_includedNodes.end(); ++it1) { for (std::set<int>::const_iterator it2 = m_includedNodes.begin(); it2 != m_includedNodes.end(); ++it2) { addArcIfThere(*it1, *it2); } } for (size_t i = 0; i < m_raceArcs.size(); ++i) { const VarsInfo::RaceInfo& race = *m_raceArcs[i].m_varInfo; if (m_includedNodes.count(race.m_event1) && m_includedNodes.count(race.m_event2)) { m_graphViz.getArc(race.m_event1, race.m_event2)->m_color = m_raceArcs[i].m_color; m_graphViz.getArc(race.m_event1, race.m_event2)->m_fontColor = m_raceArcs[i].m_color; m_graphViz.getArc(race.m_event1, race.m_event2)->m_label = race.TypeStr(); m_graphViz.getArc(race.m_event1, race.m_event2)->m_style = "dashed"; m_graphViz.getArc(race.m_event1, race.m_event2)->m_arrowHead = "dot"; StringAppendF(&m_graphViz.getArc(race.m_event1, race.m_event2)->m_url, "race?focus=%d&id=%d", m_focusNode, m_raceArcs[i].m_id); } } m_graphViz.output(m_fileName, output); }
int FieldTrial::AppendGroup(const std::string& name, Probability group_probability) { DCHECK_LE(group_probability, divisor_); DCHECK_GE(group_probability, 0); if(enable_benchmarking_ || !enable_field_trial_) { group_probability = 0; } accumulated_group_probability_ += group_probability; DCHECK_LE(accumulated_group_probability_, divisor_); if(group_==kNotFinalized && accumulated_group_probability_>random_) { // This is the group that crossed the random line, so we do the assignment. group_ = next_group_number_; if(name.empty()) { StringAppendF(&group_name_, "%d", group_); } else { group_name_ = name; } FieldTrialList::NotifyFieldTrialGroupSelection(name_, group_name_); } return next_group_number_++; }
string EvaluationToString(const ResidualBlock& block, double const* const* parameters, double* cost, double* residuals, double** jacobians) { CHECK_NOTNULL(cost); CHECK_NOTNULL(residuals); const int num_parameter_blocks = block.NumParameterBlocks(); const int num_residuals = block.NumResiduals(); string result = ""; StringAppendF(&result, "Residual Block size: %d parameter blocks x %d residuals\n\n", num_parameter_blocks, num_residuals); result += "For each parameter block, the value of the parameters are printed in the first column \n" // NOLINT "and the value of the jacobian under the corresponding residual. If a ParameterBlock was \n" // NOLINT "held constant then the corresponding jacobian is printed as 'Not Computed'. If an entry \n" // NOLINT "of the Jacobian/residual array was requested but was not written to by user code, it is \n" // NOLINT "indicated by 'Uninitialized'. This is an error. Residuals or Jacobian values evaluating \n" // NOLINT "to Inf or NaN is also an error. \n\n"; // NOLINT string space = "Residuals: "; result += space; AppendArrayToString(num_residuals, residuals, &result); StringAppendF(&result, "\n\n"); for (int i = 0; i < num_parameter_blocks; ++i) { const int parameter_block_size = block.parameter_blocks()[i]->Size(); StringAppendF( &result, "Parameter Block %d, size: %d\n", i, parameter_block_size); StringAppendF(&result, "\n"); for (int j = 0; j < parameter_block_size; ++j) { AppendArrayToString(1, parameters[i] + j, &result); StringAppendF(&result, "| "); for (int k = 0; k < num_residuals; ++k) { AppendArrayToString(1, (jacobians != NULL && jacobians[i] != NULL) ? jacobians[i] + k * parameter_block_size + j : NULL, &result); } StringAppendF(&result, "\n"); } StringAppendF(&result, "\n"); } StringAppendF(&result, "\n"); return result; }
static void printWaitMessage(const DebugOutputTarget* target, const char* detail, Object* obj, Thread* thread) { std::string msg(StringPrintf(" - waiting %s <%p> ", detail, obj)); if (obj->clazz != gDvm.classJavaLangClass) { // I(16573) - waiting on <0xf5feda38> (a java.util.LinkedList) // I(16573) - waiting on <0xf5ed54f8> (a java.lang.Class<java.lang.ref.ReferenceQueue>) msg += "(a " + dvmHumanReadableType(obj) + ")"; } if (thread != NULL) { std::string threadName(dvmGetThreadName(thread)); StringAppendF(&msg, " held by tid=%d (%s)", thread->threadId, threadName.c_str()); } dvmPrintDebugMessage(target, "%s\n", msg.c_str()); }
/* * Dump a summary of an array of references to the log file. * * This is used to dump the contents of ReferenceTable and IndirectRefTable * structs. */ void dvmDumpReferenceTableContents(Object* const* refs, size_t count, const char* descr) { LOGW("%s reference table (%p) dump:", descr, refs); if (count == 0) { LOGW(" (empty)"); return; } // Dump the most recent N entries. const size_t kLast = 10; int first = count - kLast; if (first < 0) { first = 0; } LOGW(" Last %d entries (of %d):", (count - first), count); for (int idx = count - 1; idx >= first; --idx) { const Object* ref = refs[idx]; if (ref == NULL) { continue; } if (ref == kClearedJniWeakGlobal) { LOGW(" %5d: cleared jweak", idx); continue; } if (ref->clazz == NULL) { // should only be possible right after a plain dvmMalloc(). size_t size = dvmObjectSizeInHeap(ref); LOGW(" %5d: %p (raw) (%zd bytes)", idx, ref, size); continue; } std::string className(dvmHumanReadableType(ref)); std::string extras; size_t elems = getElementCount(ref); if (elems != 0) { StringAppendF(&extras, " (%zd elements)", elems); } else if (ref->clazz == gDvm.classJavaLangString) { const StringObject* str = reinterpret_cast<const StringObject*>(ref); extras += " \""; size_t count = 0; char* s = dvmCreateCstrFromString(str); char* p = s; for (; *p && count < 16; ++p, ++count) { extras += *p; } if (*p == 0) { extras += "\""; } else { StringAppendF(&extras, "... (%d chars)", str->length()); } free(s); } LOGW(" %5d: %p %s%s", idx, ref, className.c_str(), extras.c_str()); } // Make a copy of the table, and sort it. Object** tableCopy = (Object**)malloc(sizeof(Object*) * count); if (tableCopy == NULL) { LOGE("Unable to copy table with %d elements", count); return; } memcpy(tableCopy, refs, sizeof(Object*) * count); qsort(tableCopy, count, sizeof(Object*), compareObject); refs = tableCopy; // use sorted list // Remove any uninteresting stuff from the list. The sort moved them all to the end. while (count > 0 && refs[count-1] == NULL) { --count; } while (count > 0 && refs[count-1] == kClearedJniWeakGlobal) { --count; } if (count == 0) { return; } // Dump a summary of the whole table. LOGW(" Summary:"); size_t equiv, identical; equiv = identical = 0; size_t idx; size_t elems; for (idx = 1; idx < count; idx++) { elems = getElementCount(refs[idx-1]); if (refs[idx] == refs[idx-1]) { // same reference, added more than once. identical++; } else if (refs[idx]->clazz == refs[idx-1]->clazz && getElementCount(refs[idx]) == elems) { // same class / element count, different object. equiv++; } else { // different class. logSummaryLine(refs[idx-1], elems, identical, equiv); equiv = identical = 0; } } // Handle the last entry (everything above outputs refs[i-1]). elems = getElementCount(refs[idx-1]); logSummaryLine(refs[count-1], elems, identical, equiv); free(tableCopy); }
void JSONWriter::BuildJSONString(const Value* const node, int depth, bool escape) { switch(node->GetType()) { case Value::TYPE_NULL: json_string_->append("null"); break; case Value::TYPE_BOOLEAN: { bool value; bool result = node->GetAsBoolean(&value); DCHECK(result); json_string_->append(value ? "true" : "false"); break; } case Value::TYPE_INTEGER: { int value; bool result = node->GetAsInteger(&value); DCHECK(result); StringAppendF(json_string_, "%d", value); break; } case Value::TYPE_DOUBLE: { double value; bool result = node->GetAsDouble(&value); DCHECK(result); std::string real = DoubleToString(value); // 如果没有小数位或者'e', 为数字添加一个.0. 这样可以确保读取JSON的时候 // 被解释为一个real而不是int. if(real.find('.')==std::string::npos && real.find('e')==std::string::npos && real.find('E')==std::string::npos) { real.append(".0"); } // JSON规范规定(-1,1)区间的非整数值在小数位前有一个0. ".52"是非法的, // "0.52"是合法的. if(real[0] == '.') { real.insert(0, "0"); } else if(real.length()>1 && real[0]=='-' && real[1]=='.') { // "-.1"非法 "-0.1"合法 real.insert(1, "0"); } json_string_->append(real); break; } case Value::TYPE_STRING: { std::string value; bool result = node->GetAsString(&value); DCHECK(result); if(escape) { JsonDoubleQuote(UTF8ToUTF16(value), true, json_string_); } else { JsonDoubleQuote(value, true, json_string_); } break; } case Value::TYPE_LIST: { json_string_->append("["); if(pretty_print_) { json_string_->append(" "); } const ListValue* list = static_cast<const ListValue*>(node); for(size_t i=0; i<list->GetSize(); ++i) { if(i != 0) { json_string_->append(","); if(pretty_print_) { json_string_->append(" "); } } Value* value = NULL; bool result = list->Get(i, &value); DCHECK(result); BuildJSONString(value, depth, escape); } if(pretty_print_) { json_string_->append(" "); } json_string_->append("]"); break; } case Value::TYPE_DICTIONARY: { json_string_->append("{"); if(pretty_print_) { json_string_->append(kPrettyPrintLineEnding); } const DictionaryValue* dict = static_cast<const DictionaryValue*>(node); for(DictionaryValue::key_iterator key_itr=dict->begin_keys(); key_itr!=dict->end_keys(); ++key_itr) { if(key_itr != dict->begin_keys()) { json_string_->append(","); if(pretty_print_) { json_string_->append(kPrettyPrintLineEnding); } } Value* value = NULL; bool result = dict->GetWithoutPathExpansion(*key_itr, &value); DCHECK(result); if(pretty_print_) { IndentLine(depth+1); } AppendQuotedString(*key_itr); if(pretty_print_) { json_string_->append(": "); } else { json_string_->append(":"); } BuildJSONString(value, depth+1, escape); } if(pretty_print_) { json_string_->append(kPrettyPrintLineEnding); IndentLine(depth); json_string_->append("}"); } else { json_string_->append("}"); } break; } default: // TODO: 处理TYPE_BINARY NOTREACHED() << "unknown json type"; } }