/* Dumps the facts table. */ static void dump_facts(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g) { MVMuint16 i, j, num_locals, num_facts; num_locals = g->num_locals; for (i = 0; i < num_locals; i++) { num_facts = g->fact_counts[i]; for (j = 0; j < num_facts; j++) { MVMint32 usages = g->facts[i][j].usages; MVMint32 flags = g->facts[i][j].flags; if (i < 10) append(ds, " "); if (j < 10) append(ds, " "); appendf(ds, " r%d(%d): usages=%d, flags=%-5d", i, j, usages, flags); if (flags & 1) { append(ds, " KnTyp"); } if (flags & 2) { append(ds, " KnVal"); } if (flags & 4) { append(ds, " Dcntd"); } if (flags & 8) { append(ds, " Concr"); } if (flags & 16) { append(ds, " TyObj"); } if (flags & 32) { append(ds, " KnDcT"); } if (flags & 64) { append(ds, " DCncr"); } if (flags & 128) { append(ds, " DcTyO"); } if (flags & 256) { append(ds, " LogGd"); } if (flags & 512) { append(ds, " HashI"); } if (flags & 1024) { append(ds, " ArrIt"); } if (flags & 2048) { append(ds, " KBxSr"); } if (flags & 4096) { append(ds, " MgWLG"); } if (flags & 8192) { append(ds, " KRWCn"); } if (g->facts[i][j].writer && g->facts[i][j].writer->info->opcode == MVM_SSA_PHI) { appendf(ds, " (merged from %d regs)", g->facts[i][j].writer->info->num_operands - 1); } append(ds, "\n"); } } }
static void dump_callsite(MVMThreadContext *tc, DumpStr *ds, MVMCallsite *cs) { MVMuint16 i; appendf(ds, "Callsite %p (%d args, %d pos)\n", cs, cs->arg_count, cs->num_pos); for (i = 0; i < (cs->arg_count - cs->num_pos) / 2; i++) { if (cs->arg_names[i]) { char * argname_utf8 = MVM_string_utf8_encode_C_string(tc, cs->arg_names[i]); appendf(ds, " - %s\n", argname_utf8); MVM_free(argname_utf8); } } if (cs->num_pos) append(ds, "Positional flags: "); for (i = 0; i < cs->num_pos; i++) { MVMCallsiteEntry arg_flag = cs->arg_flags[i]; if (i) append(ds, ", "); if (arg_flag == MVM_CALLSITE_ARG_OBJ) { append(ds, "obj"); } else if (arg_flag == MVM_CALLSITE_ARG_INT) { append(ds, "int"); } else if (arg_flag == MVM_CALLSITE_ARG_NUM) { append(ds, "num"); } else if (arg_flag == MVM_CALLSITE_ARG_STR) { append(ds, "str"); } } if (cs->num_pos) append(ds, "\n"); append(ds, "\n"); }
/* Dump a spesh graph into string form, for debugging purposes. */ char * MVM_spesh_dump(MVMThreadContext *tc, MVMSpeshGraph *g) { MVMSpeshBB *cur_bb; /* Allocate buffer. */ DumpStr ds; ds.alloc = 8192; ds.buffer = MVM_malloc(ds.alloc); ds.pos = 0; /* Dump name and CUID. */ append(&ds, "Spesh of '"); append_str(tc, &ds, g->sf->body.name); append(&ds, "' (cuid: "); append_str(tc, &ds, g->sf->body.cuuid); append(&ds, ", file: "); dump_fileinfo(tc, &ds, g); append(&ds, ")\n"); if (g->cs) dump_callsite(tc, &ds, g); if (g->num_arg_guards) dump_arg_guards(tc, &ds, g); if (!g->cs && !g->num_arg_guards) append(&ds, "\n"); /* Go over all the basic blocks and dump them. */ cur_bb = g->entry; while (cur_bb) { dump_bb(tc, &ds, g, cur_bb); cur_bb = cur_bb->linear_next; } /* Dump facts. */ append(&ds, "\nFacts:\n"); dump_facts(tc, &ds, g); if (g->num_spesh_slots || g->num_log_slots) { append(&ds, "\nStats:\n"); appendf(&ds, " %d spesh slots\n", g->num_spesh_slots); appendf(&ds, " %d log slots\n", g->num_log_slots); } if (g->num_log_slots) { dump_log_values(tc, &ds, g); } append(&ds, "\n"); append_null(&ds); return ds.buffer; }
static gboolean osm_create_changeset(osm_upload_context_t *context, gchar **cred) { gboolean result = FALSE; context->changeset = ILLEGAL; project_t *project = context->project; /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); char *url = g_strdup_printf("%s/changeset/create", project->server); appendf(&context->log, NULL, _("Create changeset ")); /* create changeset request */ char *xml_str = osm_generate_xml_changeset(context->comment); if(xml_str) { printf("creating changeset %s from address %p\n", url, xml_str); *cred = g_strjoin(":", context->appdata->settings->username, context->appdata->settings->password, NULL); if(osm_update_item(&context->log, xml_str, url, *cred, &context->changeset, context->proxy)) { printf("got changeset id " ITEM_ID_FORMAT "\n", context->changeset); result = TRUE; } else { g_free(*cred); } } g_free(url); return result; }
static void osm_delete_relations(osm_upload_context_t *context, gchar *cred) { relation_t *relation = context->osm->relation; project_t *project = context->project; for(; relation; relation = relation->next) { /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); if(!(OSM_FLAGS(relation) & OSM_FLAG_DELETED)) continue; printf("deleting relation on server\n"); appendf(&context->log, NULL, _("Delete relation #" ITEM_ID_FORMAT " "), OSM_ID(relation)); char *url = g_strdup_printf("%s/relation/" ITEM_ID_FORMAT, project->server, OSM_ID(relation)); char *xml_str = osm_generate_xml_relation(context->changeset, relation); if(osm_delete_item(&context->log, xml_str, url, cred, context->proxy)) { OSM_FLAGS(relation) &= ~(OSM_FLAG_DIRTY | OSM_FLAG_DELETED); project->data_dirty = TRUE; } } }
static void osm_delete_ways(osm_upload_context_t *context, gchar *cred) { way_t *way = context->osm->way; project_t *project = context->project; for(; way; way = way->next) { /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); if(!(OSM_FLAGS(way) & OSM_FLAG_DELETED)) continue; printf("deleting way on server\n"); appendf(&context->log, NULL, _("Delete way #" ITEM_ID_FORMAT " "), OSM_ID(way)); char *url = g_strdup_printf("%s/way/" ITEM_ID_FORMAT, project->server, OSM_ID(way)); char *xml_str = osm_generate_xml_way(context->changeset, way); if(osm_delete_item(&context->log, xml_str, url, cred, context->proxy)) { OSM_FLAGS(way) &= ~(OSM_FLAG_DIRTY | OSM_FLAG_DELETED); project->data_dirty = TRUE; } } }
static void osm_delete_nodes(osm_upload_context_t *context, gchar *cred) { node_t *node = context->osm->node; project_t *project = context->project; for(; node; node = node->next) { /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); if(!(OSM_FLAGS(node) & OSM_FLAG_DELETED)) continue; printf("deleting node on server\n"); appendf(&context->log, NULL, _("Delete node #" ITEM_ID_FORMAT " "), OSM_ID(node)); char *url = g_strdup_printf("%s/node/" ITEM_ID_FORMAT, project->server, OSM_ID(node)); char *xml_str = osm_generate_xml_node(context->changeset, node); if(osm_delete_item(&context->log, xml_str, url, cred, context->proxy)) { OSM_FLAGS(node) &= ~(OSM_FLAG_DIRTY | OSM_FLAG_DELETED); project->data_dirty = TRUE; } } }
/* append text, converting plain text to URL encoding */ void append_urlencode(const char *txt) { const char *p, *start; /* append in chunks as we find special characters */ for (p = start = txt ; *p != '\0' ; ++p) { char c = *p; if (isalpha(c) || isdigit(c) || strchr("-_.", c) != 0) { /* it's an ordinary character - keep it as-is */ } else { /* special character - quote it */ /* copy the part up to the special character */ if (p != start) append(start, p - start); /* append '+' for a space or a '%' encoding for others */ if (c == ' ') append("+"); else appendf("%%%02x", (int)(unsigned char)c); /* the next chunk starts at the next character */ start = p + 1; } } /* append the final chunk */ if (p != start) append(start, p - start); }
/* Dumps the statistics associated with a static frame into a string. */ char * MVM_spesh_dump_stats(MVMThreadContext *tc, MVMStaticFrame *sf) { MVMSpeshStats *ss = sf->body.spesh->body.spesh_stats; DumpStr ds; ds.alloc = 8192; ds.buffer = MVM_malloc(ds.alloc); ds.pos = 0; /* Dump name and CUID. */ append(&ds, "Latest statistics for '"); append_str(tc, &ds, sf->body.name); append(&ds, "' (cuid: "); append_str(tc, &ds, sf->body.cuuid); append(&ds, ", file: "); dump_fileinfo(tc, &ds, sf); append(&ds, ")\n\n"); /* Dump the spesh stats if present. */ if (ss) { MVMuint32 i; appendf(&ds, "Total hits: %d\n", ss->hits); if (ss->osr_hits) appendf(&ds, "OSR hits: %d\n", ss->osr_hits); append(&ds, "\n"); for (i = 0; i < ss->num_by_callsite; i++) dump_stats_by_callsite(tc, &ds, &(ss->by_callsite[i])); if (ss->num_static_values) { append(&ds, "Static values:\n"); for (i = 0; i < ss->num_static_values; i++) appendf(&ds, " - %s (%p) @ %d\n", MVM_6model_get_stable_debug_name(tc, ss->static_values[i].value->st), ss->static_values[i].value, ss->static_values[i].bytecode_offset); } } else { append(&ds, "No spesh stats for this static frame\n"); } append(&ds, "\n"); append_null(&ds); return ds.buffer; }
/* Dumps a spesh stats type typle. */ void dump_stats_type_tuple(MVMThreadContext *tc, DumpStr *ds, MVMCallsite *cs, MVMSpeshStatsType *type_tuple, char *prefix) { MVMuint32 j; for (j = 0; j < cs->flag_count; j++) { MVMObject *type = type_tuple[j].type; if (type) { MVMObject *decont_type = type_tuple[j].decont_type; appendf(ds, "%sType %d: %s%s (%s)", prefix, j, (type_tuple[j].rw_cont ? "RW " : ""), MVM_6model_get_stable_debug_name(tc, type->st), (type_tuple[j].type_concrete ? "Conc" : "TypeObj")); if (decont_type) appendf(ds, " of %s (%s)", MVM_6model_get_stable_debug_name(tc, decont_type->st), (type_tuple[j].decont_type_concrete ? "Conc" : "TypeObj")); append(ds, "\n"); } } }
static void dump_arg_guards(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g) { MVMuint16 i; appendf(ds, "%d argument guards\n", g->num_arg_guards); for (i = 0; i < g->num_arg_guards; i++) { MVMSpeshGuard *guard = &g->arg_guards[i]; switch (guard->kind) { case MVM_SPESH_GUARD_CONC: appendf(ds, " concrete(%d)\n", guard->slot); break; case MVM_SPESH_GUARD_TYPE: appendf(ds, " type(%d, %p)", guard->slot, guard->match); if (((MVMSTable*)(guard->match))->debug_name) { appendf(ds, " debugname: %s", ((MVMSTable*)(guard->match))->debug_name); } append(ds, "\n"); break; case MVM_SPESH_GUARD_DC_CONC: appendf(ds, " deconted_concrete(%d)\n", guard->slot); break; case MVM_SPESH_GUARD_DC_TYPE: appendf(ds, " deconted_type(%d, %p)", guard->slot, guard->match); if (((MVMSTable*)(guard->match))->debug_name) { appendf(ds, " debugname: %s", ((MVMSTable*)(guard->match))->debug_name); } append(ds, "\n"); break; case MVM_SPESH_GUARD_DC_CONC_RW: appendf(ds, " deconted_concrete_rw(%d)\n", guard->slot); break; case MVM_SPESH_GUARD_DC_TYPE_RW: appendf(ds, " deconted_type_rw(%d, %p)", guard->slot, guard->match); if (((MVMSTable*)(guard->match))->debug_name) { appendf(ds, " debugname: %s", ((MVMSTable*)(guard->match))->debug_name); } append(ds, "\n"); break; } } append(ds, "\n"); }
int serialize_bloom_filter(const char* key, bloom_filter* bf, output_data* output) { output->pos = 0; if (appendf(output, "if %s == nil then %s = bloom_filter.new(%d, %g) end\n", key, key, bf->items, bf->probability)) { return 1; } if (appendf(output, "%s:fromstring(\"", key)) { return 1; } if (serialize_binary(bf->data, bf->bytes, output)) return 1; if (appends(output, "\")\n")) { return 1; } return 0; }
static void dump_deopt_pea(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g) { MVMint32 i, j; if (MVM_VECTOR_ELEMS(g->deopt_pea.materialize_info)) { append(ds, "\nMaterializations:\n"); for (i = 0; i < MVM_VECTOR_ELEMS(g->deopt_pea.materialize_info); i++) { MVMSpeshPEAMaterializeInfo *mat = &(g->deopt_pea.materialize_info[i]); MVMSTable *st = (MVMSTable *)g->spesh_slots[mat->stable_sslot]; appendf(ds, " %d: %s from regs ", i, st->debug_name); for (j = 0; j < mat->num_attr_regs; j++) appendf(ds, j > 0 ? ", r%hu" : "r%hu", mat->attr_regs[j]); append(ds, "\n"); } } if (MVM_VECTOR_ELEMS(g->deopt_pea.deopt_point)) { append(ds, "\nDeopt point materialization mappings:\n"); for (i = 0; i < MVM_VECTOR_ELEMS(g->deopt_pea.deopt_point); i++) { MVMSpeshPEADeoptPoint *dp = &(g->deopt_pea.deopt_point[i]); appendf(ds, " At %d materialize %d into r%d\n", dp->deopt_point_idx, dp->materialize_info_idx, dp->target_reg); } } }
static void osm_upload_relations(osm_upload_context_t *context, gchar *cred) { relation_t *relation = context->osm->relation; project_t *project = context->project; for(; relation; relation = relation->next) { /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); if(!(OSM_FLAGS(relation) & (OSM_FLAG_DIRTY | OSM_FLAG_NEW)) || (OSM_FLAGS(relation) & OSM_FLAG_DELETED)) continue; char *url = NULL; if(OSM_FLAGS(relation) & OSM_FLAG_NEW) { url = g_strdup_printf("%s/relation/create", project->server); appendf(&context->log, NULL, _("New relation ")); } else { url = g_strdup_printf("%s/relation/" ITEM_ID_FORMAT, project->server,OSM_ID(relation)); appendf(&context->log, NULL, _("Modified relation #" ITEM_ID_FORMAT " "), OSM_ID(relation)); } /* upload this relation */ char *xml_str = osm_generate_xml_relation(context->changeset, relation); if(xml_str) { printf("uploading relation %s from address %p\n", url, xml_str); if(osm_update_item(&context->log, xml_str, url, cred, (OSM_FLAGS(relation) & OSM_FLAG_NEW) ? &(OSM_ID(relation)) : &OSM_VERSION(relation), context->proxy)) { OSM_FLAGS(relation) &= ~(OSM_FLAG_DIRTY | OSM_FLAG_NEW); project->data_dirty = TRUE; } } g_free(url); } }
static void osm_upload_ways(osm_upload_context_t *context, gchar *cred) { way_t *way = context->osm->way; project_t *project = context->project; for(; way; way = way->next) { /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); if(!(OSM_FLAGS(way) & (OSM_FLAG_DIRTY | OSM_FLAG_NEW)) || (OSM_FLAGS(way) & OSM_FLAG_DELETED)) continue; char *url = NULL; if(OSM_FLAGS(way) & OSM_FLAG_NEW) { url = g_strconcat(project->server, "/way/create", NULL); appendf(&context->log, NULL, _("New way ")); } else { url = g_strdup_printf("%s/way/" ITEM_ID_FORMAT, project->server, OSM_ID(way)); appendf(&context->log, NULL, _("Modified way #" ITEM_ID_FORMAT " "), OSM_ID(way)); } /* upload this node */ char *xml_str = osm_generate_xml_way(context->changeset, way); if(xml_str) { printf("uploading way %s from address %p\n", url, xml_str); if(osm_update_item(&context->log, xml_str, url, cred, (OSM_FLAGS(way) & OSM_FLAG_NEW) ? &(OSM_ID(way)) : &OSM_VERSION(way), context->proxy)) { OSM_FLAGS(way) &= ~(OSM_FLAG_DIRTY | OSM_FLAG_NEW); project->data_dirty = TRUE; } } g_free(url); } }
// Return a talloc'ed string formatted according to the format string in fmt. // On error, return NULL. // Valid formats: // %H, %h: hour (%H is padded with 0 to two digits) // %M: minutes from 00-59 (hours are subtracted) // %m: total minutes (includes hours, unlike %M) // %S: seconds from 00-59 (minutes and hours are subtracted) // %s: total seconds (includes hours and minutes) // %f: like %s, but as float // %T: milliseconds (000-999) char *mp_format_time_fmt(const char *fmt, double time) { if (time == MP_NOPTS_VALUE) return talloc_strdup(NULL, "unknown"); char *sign = time < 0 ? "-" : ""; time = time < 0 ? -time : time; long long int itime = time; long long int h, m, tm, s; int ms; s = itime; tm = s / 60; h = s / 3600; s -= h * 3600; m = s / 60; s -= m * 60; ms = (time - itime) * 1000; char *res = talloc_strdup(NULL, ""); while (*fmt) { if (fmt[0] == '%') { fmt++; switch (fmt[0]) { case 'h': appendf(&res, "%s%lld", sign, h); break; case 'H': appendf(&res, "%s%02lld", sign, h); break; case 'm': appendf(&res, "%s%lld", sign, tm); break; case 'M': appendf(&res, "%02lld", m); break; case 's': appendf(&res, "%s%lld", sign, itime); break; case 'S': appendf(&res, "%02lld", s); break; case 'T': appendf(&res, "%03d", ms); break; case '%': appendf(&res, "%s", "%"); break; default: goto error; } fmt++; } else { appendf(&res, "%c", *fmt); fmt++; } } return res; error: talloc_free(res); return NULL; }
/* Dump deopt usages. */ static void dump_deopt_usages(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g, MVMSpeshOperand operand) { MVMSpeshFacts *facts = MVM_spesh_get_facts(tc, g, operand); MVMSpeshDeoptUseEntry *entry = facts->usage.deopt_users; if (entry) { MVMuint32 first = 1; append(ds, ", deopt="); while (entry) { if (first) first = 0; else append(ds, ","); appendf(ds, "%d", entry->deopt_idx); entry = entry->next; } } }
static void dump_fileinfo(MVMThreadContext *tc, DumpStr *ds, MVMStaticFrame *sf) { MVMBytecodeAnnotation *ann = MVM_bytecode_resolve_annotation(tc, &sf->body, 0); MVMCompUnit *cu = sf->body.cu; MVMint32 str_idx = ann ? ann->filename_string_heap_index : 0; MVMint32 line_nr = ann ? ann->line_number : 1; MVMString *filename = cu->body.filename; char *filename_utf8 = "<unknown>"; if (ann && str_idx < cu->body.num_strings) { filename = MVM_cu_string(tc, cu, str_idx); } if (filename) filename_utf8 = MVM_string_utf8_encode_C_string(tc, filename); appendf(ds, "%s:%d", filename_utf8, line_nr); if (filename) MVM_free(filename_utf8); MVM_free(ann); }
static gboolean osm_close_changeset(osm_upload_context_t *context, gchar *cred) { gboolean result = FALSE; project_t *project = context->project; g_assert(context->changeset != ILLEGAL); /* make sure gui gets updated */ while(gtk_events_pending()) gtk_main_iteration(); char *url = g_strdup_printf("%s/changeset/" ITEM_ID_FORMAT "/close", project->server, context->changeset); appendf(&context->log, NULL, _("Close changeset ")); if(osm_update_item(&context->log, NULL, url, cred, NULL, context->proxy)) result = TRUE; g_free(cred); g_free(url); return result; }
int serialize_data_as_json(lua_sandbox* lsb, int index, output_data* output) { const char* s; size_t len = 0; size_t start_pos = output->pos; size_t escaped_len = 0; switch (lua_type(lsb->lua, index)) { case LUA_TNUMBER: if (serialize_double(output, lua_tonumber(lsb->lua, index))) { return 1; } break; case LUA_TSTRING: s = lua_tolstring(lsb->lua, index, &len); escaped_len = len + 3; // account for the quotes and terminator if (output->pos + escaped_len > output->size) { if (realloc_output(output, escaped_len)) return 1; } output->data[output->pos++] = '"'; for (size_t i = 0; i < len; ++i) { // buffer needs at least enough room for an escaped character, an end // quote and a null terminator if (output->pos + 4 > output->size) { size_t needed = escaped_len - (output->pos - start_pos); if (realloc_output(output, needed)) return 1; } switch (s[i]) { case '"': output->data[output->pos++] = '\\'; output->data[output->pos++] = '"'; ++escaped_len; break; case '\\': output->data[output->pos++] = '\\'; output->data[output->pos++] = '\\'; ++escaped_len; break; case '/': output->data[output->pos++] = '\\'; output->data[output->pos++] = '/'; ++escaped_len; break; case '\b': output->data[output->pos++] = '\\'; output->data[output->pos++] = 'b'; ++escaped_len; break; case '\f': output->data[output->pos++] = '\\'; output->data[output->pos++] = 'f'; ++escaped_len; break; case '\n': output->data[output->pos++] = '\\'; output->data[output->pos++] = 'n'; ++escaped_len; break; case '\r': output->data[output->pos++] = '\\'; output->data[output->pos++] = 'r'; ++escaped_len; break; case '\t': output->data[output->pos++] = '\\'; output->data[output->pos++] = 't'; ++escaped_len; break; default: output->data[output->pos++] = s[i]; } } output->data[output->pos++] = '"'; output->data[output->pos] = 0; break; case LUA_TBOOLEAN: if (appendf(output, "%s", lua_toboolean(lsb->lua, index) ? "true" : "false")) { return 1; } case LUA_TNIL: break; default: snprintf(lsb->error_message, LSB_ERROR_SIZE, "serialize_data_as_json cannot preserve type '%s'", lua_typename(lsb->lua, lua_type(lsb->lua, index))); return 1; } return 0; }
/* Dumps a basic block. */ static void dump_bb(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g, MVMSpeshBB *bb) { MVMSpeshIns *cur_ins; MVMint64 i; /* Heading. */ appendf(ds, " BB %d:\n", bb->idx); /* Instructions. */ append(ds, " Instructions:\n"); cur_ins = bb->first_ins; while (cur_ins) { MVMSpeshAnn *ann = cur_ins->annotations; while (ann) { switch (ann->type) { case MVM_SPESH_ANN_FH_START: appendf(ds, " [Annotation: FH Start (%d)]\n", ann->data.frame_handler_index); break; case MVM_SPESH_ANN_FH_END: appendf(ds, " [Annotation: FH End (%d)]\n", ann->data.frame_handler_index); break; case MVM_SPESH_ANN_FH_GOTO: appendf(ds, " [Annotation: FH Goto (%d)]\n", ann->data.frame_handler_index); break; default: appendf(ds, " [Annotation: %d (unknown)]\n", ann->type); } ann = ann->next; } appendf(ds, " %s ", cur_ins->info->name); if (cur_ins->info->opcode == MVM_SSA_PHI) { for (i = 0; i < cur_ins->info->num_operands; i++) { if (i) append(ds, ", "); appendf(ds, "r%d(%d)", cur_ins->operands[i].reg.orig, cur_ins->operands[i].reg.i); } } else { for (i = 0; i < cur_ins->info->num_operands; i++) { if (i) append(ds, ", "); switch (cur_ins->info->operands[i] & MVM_operand_rw_mask) { case MVM_operand_read_reg: case MVM_operand_write_reg: appendf(ds, "r%d(%d)", cur_ins->operands[i].reg.orig, cur_ins->operands[i].reg.i); break; case MVM_operand_literal: { MVMuint32 type = cur_ins->info->operands[i] & MVM_operand_type_mask; switch (type) { case MVM_operand_ins: appendf(ds, "BB(%d)", cur_ins->operands[i].ins_bb->idx); break; case MVM_operand_int8: appendf(ds, "liti8(%d)", cur_ins->operands[i].lit_i8); break; case MVM_operand_int16: appendf(ds, "liti16(%d)", cur_ins->operands[i].lit_i16); break; case MVM_operand_int32: appendf(ds, "liti32(%d)", cur_ins->operands[i].lit_i32); break; case MVM_operand_int64: appendf(ds, "liti64(%d)", cur_ins->operands[i].lit_i64); break; case MVM_operand_num32: appendf(ds, "litn32(%d)", cur_ins->operands[i].lit_n32); break; case MVM_operand_num64: appendf(ds, "litn64(%d)", cur_ins->operands[i].lit_n64); break; default: append(ds, "<nyi(lit)>"); } break; } default: append(ds, "<nyi>"); } } } append(ds, "\n"); cur_ins = cur_ins->next; } /* Predecessors and successors. */ append(ds, " Successors: "); for (i = 0; i < bb->num_succ; i++) appendf(ds, (i == 0 ? "%d" : ", %d"), bb->succ[i]->idx); append(ds, "\n Predeccessors: "); for (i = 0; i < bb->num_pred; i++) appendf(ds, (i == 0 ? "%d" : ", %d"), bb->pred[i]->idx); append(ds, "\n Dominance children: "); for (i = 0; i < bb->num_children; i++) appendf(ds, (i == 0 ? "%d" : ", %d"), bb->children[i]->idx); append(ds, "\n\n"); }
/* Dumps a static frame's guard set into a string. */ char * MVM_spesh_dump_arg_guard(MVMThreadContext *tc, MVMStaticFrame *sf) { MVMSpeshArgGuard *ag = sf->body.spesh->body.spesh_arg_guard; DumpStr ds; ds.alloc = 8192; ds.buffer = MVM_malloc(ds.alloc); ds.pos = 0; /* Dump name and CUID. */ append(&ds, "Latest guard tree for '"); append_str(tc, &ds, sf->body.name); append(&ds, "' (cuid: "); append_str(tc, &ds, sf->body.cuuid); append(&ds, ", file: "); dump_fileinfo(tc, &ds, sf); append(&ds, ")\n\n"); /* Dump nodes. */ if (ag) { MVMuint32 i = 0; for (i = 0; i < ag->used_nodes; i++) { MVMSpeshArgGuardNode *agn = &(ag->nodes[i]); switch (agn->op) { case MVM_SPESH_GUARD_OP_CALLSITE: appendf(&ds, "%u: CALLSITE %p | Y: %u, N: %u\n", i, agn->cs, agn->yes, agn->no); break; case MVM_SPESH_GUARD_OP_LOAD_ARG: appendf(&ds, "%u: LOAD ARG %d | Y: %u\n", i, agn->arg_index, agn->yes); break; case MVM_SPESH_GUARD_OP_STABLE_CONC: appendf(&ds, "%u: STABLE CONC %s | Y: %u, N: %u\n", i, MVM_6model_get_stable_debug_name(tc, agn->st), agn->yes, agn->no); break; case MVM_SPESH_GUARD_OP_STABLE_TYPE: appendf(&ds, "%u: STABLE CONC %s | Y: %u, N: %u\n", i, MVM_6model_get_stable_debug_name(tc, agn->st), agn->yes, agn->no); break; case MVM_SPESH_GUARD_OP_DEREF_VALUE: appendf(&ds, "%u: DEREF_VALUE %u | Y: %u, N: %u\n", i, agn->offset, agn->yes, agn->no); break; case MVM_SPESH_GUARD_OP_DEREF_RW: appendf(&ds, "%u: DEREF_RW %u | Y: %u, N: %u\n", i, agn->offset, agn->yes, agn->no); break; case MVM_SPESH_GUARD_OP_CERTAIN_RESULT: appendf(&ds, "%u: CERTAIN RESULT %u\n", i, agn->result); break; case MVM_SPESH_GUARD_OP_RESULT: appendf(&ds, "%u: RESULT %u\n", i, agn->result); break; } } } else { append(&ds, "No argument guard nodes\n"); } append(&ds, "\n"); append_null(&ds); return ds.buffer; }
/* Dumps a basic block. */ static void dump_bb(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g, MVMSpeshBB *bb, SpeshGraphSizeStats *stats, InlineIndexStack *inline_stack) { MVMSpeshIns *cur_ins; MVMint64 i; MVMint32 size = 0; /* Heading. */ appendf(ds, " BB %d (%p):\n", bb->idx, bb); if (bb->inlined) { append(ds, " Inlined\n"); } { /* Also, we have a line number */ MVMBytecodeAnnotation *bbba = MVM_bytecode_resolve_annotation(tc, &g->sf->body, bb->initial_pc); MVMuint32 line_number; if (bbba) { line_number = bbba->line_number; MVM_free(bbba); } else { line_number = -1; } appendf(ds, " line: %d (pc %d)\n", line_number, bb->initial_pc); } /* Instructions. */ append(ds, " Instructions:\n"); cur_ins = bb->first_ins; while (cur_ins) { MVMSpeshAnn *ann = cur_ins->annotations; MVMuint32 line_number; MVMuint32 pop_inlines = 0; MVMuint32 num_comments = 0; while (ann) { /* These four annotations carry a deopt index that we can find a * corresponding line number for */ if (ann->type == MVM_SPESH_ANN_DEOPT_ONE_INS || ann->type == MVM_SPESH_ANN_DEOPT_ALL_INS || ann->type == MVM_SPESH_ANN_DEOPT_INLINE || ann->type == MVM_SPESH_ANN_DEOPT_OSR) { MVMBytecodeAnnotation *ba = MVM_bytecode_resolve_annotation(tc, &g->sf->body, g->deopt_addrs[2 * ann->data.deopt_idx]); if (ba) { line_number = ba->line_number; MVM_free(ba); } else { line_number = -1; } } switch (ann->type) { case MVM_SPESH_ANN_FH_START: appendf(ds, " [Annotation: FH Start (%d)]\n", ann->data.frame_handler_index); break; case MVM_SPESH_ANN_FH_END: appendf(ds, " [Annotation: FH End (%d)]\n", ann->data.frame_handler_index); break; case MVM_SPESH_ANN_FH_GOTO: appendf(ds, " [Annotation: FH Goto (%d)]\n", ann->data.frame_handler_index); break; case MVM_SPESH_ANN_DEOPT_ONE_INS: appendf(ds, " [Annotation: INS Deopt One (idx %d -> pc %d; line %d)]\n", ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number); break; case MVM_SPESH_ANN_DEOPT_ALL_INS: appendf(ds, " [Annotation: INS Deopt All (idx %d -> pc %d; line %d)]\n", ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number); break; case MVM_SPESH_ANN_INLINE_START: appendf(ds, " [Annotation: Inline Start (%d)]\n", ann->data.inline_idx); push_inline(tc, inline_stack, ann->data.inline_idx); break; case MVM_SPESH_ANN_INLINE_END: appendf(ds, " [Annotation: Inline End (%d)]\n", ann->data.inline_idx); pop_inlines++; break; case MVM_SPESH_ANN_DEOPT_INLINE: appendf(ds, " [Annotation: INS Deopt Inline (idx %d -> pc %d; line %d)]\n", ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number); break; case MVM_SPESH_ANN_DEOPT_OSR: appendf(ds, " [Annotation: INS Deopt OSR (idx %d -> pc %d); line %d]\n", ann->data.deopt_idx, g->deopt_addrs[2 * ann->data.deopt_idx], line_number); break; case MVM_SPESH_ANN_LINENO: { char *cstr; MVMCompUnit *cu = get_current_cu(tc, g, inline_stack); if (cu->body.num_strings < ann->data.lineno.filename_string_index) { appendf(ds, " [Annotation: Line Number: <out of bounds>:%d]\n", ann->data.lineno.line_number); } else { cstr = MVM_string_utf8_encode_C_string(tc, MVM_cu_string(tc, get_current_cu(tc, g, inline_stack), ann->data.lineno.filename_string_index)); appendf(ds, " [Annotation: Line Number: %s:%d]\n", cstr, ann->data.lineno.line_number); MVM_free(cstr); } break; } case MVM_SPESH_ANN_LOGGED: appendf(ds, " [Annotation: Logged (bytecode offset %d)]\n", ann->data.bytecode_offset); break; case MVM_SPESH_ANN_DEOPT_SYNTH: appendf(ds, " [Annotation: INS Deopt Synth (idx %d)]\n", ann->data.deopt_idx); break; case MVM_SPESH_ANN_COMMENT: num_comments++; break; default: appendf(ds, " [Annotation: %d (unknown)]\n", ann->type); } ann = ann->next; } while (pop_inlines--) pop_inline(tc, inline_stack); if (num_comments > 1) { ann = cur_ins->annotations; while (ann) { if (ann->type == MVM_SPESH_ANN_COMMENT) { appendf(ds, " # %s\n", ann->data.comment); } ann = ann->next; } } appendf(ds, " %-15s ", cur_ins->info->name); if (cur_ins->info->opcode == MVM_SSA_PHI) { for (i = 0; i < cur_ins->info->num_operands; i++) { MVMint16 orig = cur_ins->operands[i].reg.orig; MVMint16 regi = cur_ins->operands[i].reg.i; if (i) append(ds, ", "); if (orig < 10) append(ds, " "); if (regi < 10) append(ds, " "); appendf(ds, "r%d(%d)", orig, regi); } } else { /* Count the opcode itself */ size += 2; for (i = 0; i < cur_ins->info->num_operands; i++) { if (i) append(ds, ", "); switch (cur_ins->info->operands[i] & MVM_operand_rw_mask) { case MVM_operand_read_reg: case MVM_operand_write_reg: { MVMint16 orig = cur_ins->operands[i].reg.orig; MVMint16 regi = cur_ins->operands[i].reg.i; if (orig < 10) append(ds, " "); if (regi < 10) append(ds, " "); appendf(ds, "r%d(%d)", orig, regi); size += 4; break; } case MVM_operand_read_lex: case MVM_operand_write_lex: { MVMStaticFrameBody *cursor = &g->sf->body; MVMuint32 ascension; appendf(ds, "lex(idx=%d,outers=%d", cur_ins->operands[i].lex.idx, cur_ins->operands[i].lex.outers); for (ascension = 0; ascension < cur_ins->operands[i].lex.outers; ascension++, cursor = &cursor->outer->body) { }; if (cursor->fully_deserialized) { if (cur_ins->operands[i].lex.idx < cursor->num_lexicals) { char *cstr = MVM_string_utf8_encode_C_string(tc, cursor->lexical_names_list[cur_ins->operands[i].lex.idx]->key); appendf(ds, ",%s)", cstr); MVM_free(cstr); } else { append(ds, ",<out of bounds>)"); } } else { append(ds, ",<pending deserialization>)"); } size += 4; break; } case MVM_operand_literal: { MVMuint32 type = cur_ins->info->operands[i] & MVM_operand_type_mask; switch (type) { case MVM_operand_ins: { MVMint32 bb_idx = cur_ins->operands[i].ins_bb->idx; if (bb_idx < 100) append(ds, " "); if (bb_idx < 10) append(ds, " "); appendf(ds, "BB(%d)", bb_idx); size += 4; break; } case MVM_operand_int8: appendf(ds, "liti8(%"PRId8")", cur_ins->operands[i].lit_i8); size += 2; break; case MVM_operand_int16: appendf(ds, "liti16(%"PRId16")", cur_ins->operands[i].lit_i16); size += 2; break; case MVM_operand_int32: appendf(ds, "liti32(%"PRId32")", cur_ins->operands[i].lit_i32); size += 4; break; case MVM_operand_uint32: appendf(ds, "litui32(%"PRIu32")", cur_ins->operands[i].lit_ui32); size += 4; break; case MVM_operand_int64: appendf(ds, "liti64(%"PRId64")", cur_ins->operands[i].lit_i64); size += 8; break; case MVM_operand_num32: appendf(ds, "litn32(%f)", cur_ins->operands[i].lit_n32); size += 4; break; case MVM_operand_num64: appendf(ds, "litn64(%g)", cur_ins->operands[i].lit_n64); size += 8; break; case MVM_operand_str: { char *cstr = MVM_string_utf8_encode_C_string(tc, MVM_cu_string(tc, g->sf->body.cu, cur_ins->operands[i].lit_str_idx)); appendf(ds, "lits(%s)", cstr); MVM_free(cstr); size += 8; break; } case MVM_operand_callsite: { MVMCallsite *callsite = g->sf->body.cu->body.callsites[cur_ins->operands[i].callsite_idx]; appendf(ds, "callsite(%p, %d arg, %d pos, %s, %s)", callsite, callsite->arg_count, callsite->num_pos, callsite->has_flattening ? "flattening" : "nonflattening", callsite->is_interned ? "interned" : "noninterned"); size += 2; break; } case MVM_operand_spesh_slot: appendf(ds, "sslot(%"PRId16")", cur_ins->operands[i].lit_i16); size += 2; break; case MVM_operand_coderef: { MVMCodeBody *body = &((MVMCode*)g->sf->body.cu->body.coderefs[cur_ins->operands[i].coderef_idx])->body; MVMBytecodeAnnotation *anno = MVM_bytecode_resolve_annotation(tc, &body->sf->body, 0); append(ds, "coderef("); if (anno) { char *filestr = MVM_string_utf8_encode_C_string(tc, MVM_cu_string(tc, g->sf->body.cu, anno->filename_string_heap_index)); appendf(ds, "%s:%d%s)", filestr, anno->line_number, body->outer ? " (closure)" : ""); MVM_free(filestr); } else { append(ds, "??\?)"); } size += 2; MVM_free(anno); break; } default: append(ds, "<nyi(lit)>"); } break; } default: append(ds, "<nyi>"); } } if (cur_ins->info->opcode == MVM_OP_wval || cur_ins->info->opcode == MVM_OP_wval_wide) { /* We can try to find out what the debug_name of this thing is. */ MVMint16 dep = cur_ins->operands[1].lit_i16; MVMint64 idx; MVMCollectable *result = NULL; MVMSerializationContext *sc; char *debug_name = NULL; const char *repr_name = NULL; if (cur_ins->info->opcode == MVM_OP_wval) { idx = cur_ins->operands[2].lit_i16; } else { idx = cur_ins->operands[2].lit_i64; } sc = MVM_sc_get_sc(tc, g->sf->body.cu, dep); if (sc) result = (MVMCollectable *)MVM_sc_try_get_object(tc, sc, idx); if (result) { if (result->flags & MVM_CF_STABLE) { debug_name = MVM_6model_get_stable_debug_name(tc, (MVMSTable *)result); repr_name = ((MVMSTable *)result)->REPR->name; } else { debug_name = MVM_6model_get_debug_name(tc, (MVMObject *)result); repr_name = REPR(result)->name; } if (debug_name) { appendf(ds, " (%s: %s)", repr_name, debug_name); } else { appendf(ds, " (%s: ?)", repr_name); } } else { appendf(ds, " (not deserialized)"); } } } if (num_comments == 1) { ann = cur_ins->annotations; while (ann) { if (ann->type == MVM_SPESH_ANN_COMMENT) { appendf(ds, " # %s", ann->data.comment); break; } ann = ann->next; } } append(ds, "\n"); cur_ins = cur_ins->next; } if (stats) { if (bb->inlined) stats->inlined_size += size; stats->total_size += size; } /* Predecessors and successors. */ append(ds, " Successors: "); for (i = 0; i < bb->num_succ; i++) appendf(ds, (i == 0 ? "%d" : ", %d"), bb->succ[i]->idx); append(ds, "\n Predecessors: "); for (i = 0; i < bb->num_pred; i++) appendf(ds, (i == 0 ? "%d" : ", %d"), bb->pred[i]->idx); append(ds, "\n Dominance children: "); for (i = 0; i < bb->num_children; i++) appendf(ds, (i == 0 ? "%d" : ", %d"), bb->children[i]->idx); append(ds, "\n\n"); }
/* Dumps a planned specialization into a string. */ char * MVM_spesh_dump_planned(MVMThreadContext *tc, MVMSpeshPlanned *p) { DumpStr ds; ds.alloc = 8192; ds.buffer = MVM_malloc(ds.alloc); ds.pos = 0; /* Dump kind of specialization and target. */ switch (p->kind) { case MVM_SPESH_PLANNED_CERTAIN: append(&ds, "Certain"); break; case MVM_SPESH_PLANNED_OBSERVED_TYPES: append(&ds, "Observed type"); break; case MVM_SPESH_PLANNED_DERIVED_TYPES: append(&ds, "Derived type"); break; } append(&ds, " specialization of '"); append_str(tc, &ds, p->sf->body.name); append(&ds, "' (cuid: "); append_str(tc, &ds, p->sf->body.cuuid); append(&ds, ", file: "); dump_fileinfo(tc, &ds, p->sf); append(&ds, ")\n\n"); /* Dump the callsite of the specialization. */ if (p->cs_stats->cs) { append(&ds, "The specialization is for the callsite:\n"); dump_callsite(tc, &ds, p->cs_stats->cs); } else { append(&ds, "The specialization is for when there is no interned callsite.\n"); } /* Dump reasoning. */ switch (p->kind) { case MVM_SPESH_PLANNED_CERTAIN: if (p->cs_stats->hits >= MVM_spesh_threshold(tc, p->sf)) appendf(&ds, "It was planned due to the callsite receiving %u hits.\n", p->cs_stats->hits); else if (p->cs_stats->osr_hits >= MVM_SPESH_PLAN_CS_MIN_OSR) appendf(&ds, "It was planned due to the callsite receiving %u OSR hits.\n", p->cs_stats->osr_hits); else append(&ds, "It was planned for unknown reasons.\n"); if (!p->sf->body.specializable) append(&ds, "The body contains no specializable instructions.\n"); break; case MVM_SPESH_PLANNED_OBSERVED_TYPES: { MVMCallsite *cs = p->cs_stats->cs; MVMuint32 hit_percent = p->cs_stats->hits ? (100 * p->type_stats[0]->hits) / p->cs_stats->hits : 0; MVMuint32 osr_hit_percent = p->cs_stats->osr_hits ? (100 * p->type_stats[0]->osr_hits) / p->cs_stats->osr_hits : 0; append(&ds, "It was planned for the type tuple:\n"); dump_stats_type_tuple(tc, &ds, cs, p->type_tuple, " "); if (osr_hit_percent >= MVM_SPESH_PLAN_TT_OBS_PERCENT_OSR) appendf(&ds, "Which received %u OSR hits (%u%% of the %u callsite OSR hits).\n", p->type_stats[0]->osr_hits, osr_hit_percent, p->cs_stats->osr_hits); else if (hit_percent >= MVM_SPESH_PLAN_TT_OBS_PERCENT) appendf(&ds, "Which received %u hits (%u%% of the %u callsite hits).\n", p->type_stats[0]->hits, hit_percent, p->cs_stats->hits); else append(&ds, "For unknown reasons.\n"); break; } case MVM_SPESH_PLANNED_DERIVED_TYPES: break; } appendf(&ds, "\nThe maximum stack depth is %d.\n\n", p->max_depth); append_null(&ds); return ds.buffer; }
static gboolean osm_delete_item(struct log_s *log, char *xml_str, char *url, char *user, proxy_t *proxy) { int retry = MAX_TRY; char buffer[CURL_ERROR_SIZE]; CURL *curl; CURLcode res; /* delete has a payload since api 0.6 */ curl_data_t read_data; curl_data_t write_data; while(retry >= 0) { if(retry != MAX_TRY) appendf(log, NULL, _("Retry %d/%d "), MAX_TRY-retry, MAX_TRY-1); /* get a curl handle */ curl = curl_easy_init(); if(!curl) { appendf(log, NULL, _("CURL init error\n")); return FALSE; } read_data.ptr = xml_str; read_data.len = xml_str?strlen(xml_str):0; write_data.ptr = NULL; write_data.len = 0; /* we want to use our own read/write functions */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_INFILESIZE, (curl_off_t)read_data.len); /* now specify which file to upload */ curl_easy_setopt(curl, CURLOPT_READDATA, &read_data); /* we pass our 'chunk' struct to the callback function */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_data); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* no read/write functions required */ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); /* specify target URL, and note that this URL should include a file name, not only a directory */ curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); /* some servers don't like requests that are made without a user-agent field, so we provide one */ curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE "-libcurl/" VERSION); #ifdef NO_EXPECT struct curl_slist *slist = NULL; slist = curl_slist_append(slist, "Expect:"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); #endif curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer); /* set user name and password for the authentication */ curl_easy_setopt(curl, CURLOPT_USERPWD, user); net_io_set_proxy(curl, proxy); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); long response; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); /* always cleanup */ #ifdef NO_EXPECT curl_slist_free_all(slist); #endif curl_easy_cleanup(curl); if(res != 0) appendf(log, COLOR_ERR, _("failed: %s\n"), buffer); else if(response != 200) appendf(log, COLOR_ERR, _("failed, code: %ld %s\n"), response, osm_http_message(response)); else appendf(log, COLOR_OK, _("ok\n")); /* if it's neither "ok" (200), nor "internal server error" (500) */ /* then write the message to the log */ if((response != 200) && (response != 500) && write_data.ptr) { appendf(log, NULL, _("Server reply: ")); appendf(log, COLOR_ERR, _("%s\n"), write_data.ptr); } g_free(write_data.ptr); /* don't retry unless we had an "internal server error" */ if(response != 500) return((res == 0)&&(response == 200)); retry--; } return FALSE; }
/* Dumps the statistics associated with a particular callsite object. */ void dump_stats_by_callsite(MVMThreadContext *tc, DumpStr *ds, MVMSpeshStatsByCallsite *css) { MVMuint32 i, j, k; if (css->cs) dump_callsite(tc, ds, css->cs); else append(ds, "No interned callsite\n"); appendf(ds, " Callsite hits: %d\n\n", css->hits); if (css->osr_hits) appendf(ds, " OSR hits: %d\n\n", css->osr_hits); appendf(ds, " Maximum stack depth: %d\n\n", css->max_depth); for (i = 0; i < css->num_by_type; i++) { MVMSpeshStatsByType *tss = &(css->by_type[i]); appendf(ds, " Type tuple %d\n", i); dump_stats_type_tuple(tc, ds, css->cs, tss->arg_types, " "); appendf(ds, " Hits: %d\n", tss->hits); if (tss->osr_hits) appendf(ds, " OSR hits: %d\n", tss->osr_hits); appendf(ds, " Maximum stack depth: %d\n", tss->max_depth); if (tss->num_by_offset) { append(ds, " Logged at offset:\n"); for (j = 0; j < tss->num_by_offset; j++) { MVMSpeshStatsByOffset *oss = &(tss->by_offset[j]); appendf(ds, " %d:\n", oss->bytecode_offset); for (k = 0; k < oss->num_types; k++) appendf(ds, " %d x type %s (%s)\n", oss->types[k].count, MVM_6model_get_stable_debug_name(tc, oss->types[k].type->st), (oss->types[k].type_concrete ? "Conc" : "TypeObj")); for (k = 0; k < oss->num_invokes; k++) { char *body_name = MVM_string_utf8_encode_C_string(tc, oss->invokes[k].sf->body.name); char *body_cuuid = MVM_string_utf8_encode_C_string(tc, oss->invokes[k].sf->body.cuuid); appendf(ds, " %d x static frame '%s' (%s) (caller is outer: %d, multi %d)\n", oss->invokes[k].count, body_name, body_cuuid, oss->invokes[k].caller_is_outer_count, oss->invokes[k].was_multi_count); MVM_free(body_name); MVM_free(body_cuuid); } for (k = 0; k < oss->num_type_tuples; k++) { appendf(ds, " %d x type tuple:\n", oss->type_tuples[k].count); dump_stats_type_tuple(tc, ds, oss->type_tuples[k].cs, oss->type_tuples[k].arg_types, " "); } for (k = 0; k < oss->num_plugin_guards; k++) appendf(ds, " %d x spesh plugin guard index %d\n", oss->plugin_guards[k].count, oss->plugin_guards[k].guard_index); } } append(ds, "\n"); } }
/* Dump a spesh graph into string form, for debugging purposes. */ char * MVM_spesh_dump(MVMThreadContext *tc, MVMSpeshGraph *g) { MVMSpeshBB *cur_bb; SpeshGraphSizeStats stats; InlineIndexStack inline_stack; DumpStr ds; stats.total_size = 0; stats.inlined_size = 0; inline_stack.cur_depth = -1; /* Allocate buffer. */ ds.alloc = 8192; ds.buffer = MVM_malloc(ds.alloc); ds.pos = 0; /* Dump name and CUID. */ append(&ds, "Spesh of '"); append_str(tc, &ds, g->sf->body.name); append(&ds, "' (cuid: "); append_str(tc, &ds, g->sf->body.cuuid); append(&ds, ", file: "); dump_fileinfo(tc, &ds, g->sf); append(&ds, ")\n"); if (g->cs) dump_callsite(tc, &ds, g->cs); if (!g->cs) append(&ds, "\n"); /* Go over all the basic blocks and dump them. */ cur_bb = g->entry; while (cur_bb) { dump_bb(tc, &ds, g, cur_bb, &stats, &inline_stack); cur_bb = cur_bb->linear_next; } /* Dump facts. */ if (g->facts) { append(&ds, "\nFacts:\n"); dump_facts(tc, &ds, g); } /* Dump spesh slots. */ if (g->num_spesh_slots) { MVMuint32 i; append(&ds, "\nSpesh slots:\n"); for (i = 0; i < g->num_spesh_slots; i++) { MVMCollectable *value = g->spesh_slots[i]; if (value == NULL) appendf(&ds, " %d = NULL\n", i); else if (value->flags & MVM_CF_STABLE) appendf(&ds, " %d = STable (%s)\n", i, MVM_6model_get_stable_debug_name(tc, (MVMSTable *)value)); else if (value->flags & MVM_CF_TYPE_OBJECT) appendf(&ds, " %d = Type Object (%s)\n", i, MVM_6model_get_debug_name(tc, (MVMObject *)value)); else { MVMObject *obj = (MVMObject *)value; MVMuint32 repr_id = REPR(obj)->ID; appendf(&ds, " %d = Instance (%s)", i, MVM_6model_get_debug_name(tc, obj)); if (repr_id == MVM_REPR_ID_MVMStaticFrame || repr_id == MVM_REPR_ID_MVMCode) { MVMStaticFrameBody *body; char *name_str; char *cuuid_str; if (repr_id == MVM_REPR_ID_MVMCode) { MVMCodeBody *code_body = (MVMCodeBody *)OBJECT_BODY(obj); obj = (MVMObject *)code_body->sf; } body = (MVMStaticFrameBody *)OBJECT_BODY(obj); name_str = MVM_string_utf8_encode_C_string(tc, body->name); cuuid_str = MVM_string_utf8_encode_C_string(tc, body->cuuid); appendf(&ds, " - '%s' (%s)", name_str, cuuid_str); MVM_free(name_str); MVM_free(cuuid_str); } appendf(&ds, "\n"); } } } /* Dump materialization deopt into. */ dump_deopt_pea(tc, &ds, g); append(&ds, "\n"); /* Print out frame size */ if (stats.inlined_size) appendf(&ds, "Frame size: %u bytes (%u from inlined frames)\n", stats.total_size, stats.inlined_size); else appendf(&ds, "Frame size: %u bytes\n", stats.total_size); append_null(&ds); return ds.buffer; }
void osm_upload(appdata_t *appdata, osm_t *osm, project_t *project) { printf("starting upload\n"); /* upload config and confirmation dialog */ /* count nodes */ osm_dirty_t dirty; memset(&dirty, 0, sizeof(dirty)); const node_t *node = osm->node; while(node) { object_counter(OSM_BASE(node), &dirty.nodes); node = node->next; } printf("nodes: new %2d, dirty %2d, deleted %2d\n", dirty.nodes.added, dirty.nodes.dirty, dirty.nodes.deleted); /* count ways */ const way_t *way = osm->way; while(way) { object_counter(OSM_BASE(way), &dirty.ways); way = way->next; } printf("ways: new %2d, dirty %2d, deleted %2d\n", dirty.ways.added, dirty.ways.dirty, dirty.ways.deleted); /* count relations */ const relation_t *relation = osm->relation; while(relation) { object_counter(OSM_BASE(relation), &dirty.relations); relation = relation->next; } printf("relations: new %2d, dirty %2d, deleted %2d\n", dirty.relations.added, dirty.relations.dirty, dirty.relations.deleted); GtkWidget *dialog = misc_dialog_new(MISC_DIALOG_MEDIUM, _("Upload to OSM"), GTK_WINDOW(appdata->window), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); GtkWidget *table = gtk_table_new(4, 5, TRUE); table_attach_label_c(table, _("Total"), 1, 2, 0, 1); table_attach_label_c(table, _("New"), 2, 3, 0, 1); table_attach_label_c(table, _("Modified"), 3, 4, 0, 1); table_attach_label_c(table, _("Deleted"), 4, 5, 0, 1); int row = 1; table_attach_label_l(table, _("Nodes:"), 0, 1, row, row + 1); table_insert_count(table, &dirty.nodes, row++); table_attach_label_l(table, _("Ways:"), 0, 1, row, row + 1); table_insert_count(table, &dirty.ways, row++); table_attach_label_l(table, _("Relations:"), 0, 1, row, row + 1); table_insert_count(table, &dirty.relations, row++); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0); /* ------------------------------------------------------ */ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_hseparator_new(), FALSE, FALSE, 0); /* ------- add username and password entries ------------ */ table = gtk_table_new(2, 2, FALSE); table_attach_label_l(table, _("Username:"******"Password:"******"Please add a comment"), -1); /* disable ok button until user edited the comment */ gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, FALSE); g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(callback_buffer_modified), dialog); #ifndef FREMANTLE GtkWidget *view = gtk_text_view_new_with_buffer(buffer); #else GtkWidget *view = hildon_text_view_new(); hildon_text_view_set_buffer(HILDON_TEXT_VIEW(view), buffer); #endif gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD); gtk_text_view_set_editable(GTK_TEXT_VIEW(view), TRUE); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 2 ); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 2 ); g_object_set_data(G_OBJECT(view), "first_click", GINT_TO_POINTER(TRUE)); g_signal_connect(G_OBJECT(view), "focus-in-event", G_CALLBACK(cb_focus_in), buffer); gtk_container_add(GTK_CONTAINER(scrolled_win), view); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrolled_win); gtk_widget_show_all(dialog); if(GTK_RESPONSE_ACCEPT != gtk_dialog_run(GTK_DIALOG(dialog))) { printf("upload cancelled\n"); gtk_widget_destroy(dialog); return; } printf("clicked ok\n"); /* retrieve username and password */ g_free(appdata->settings->username); appdata->settings->username = g_strdup(gtk_entry_get_text(GTK_ENTRY(uentry))); g_free(appdata->settings->password); appdata->settings->password = g_strdup(gtk_entry_get_text(GTK_ENTRY(pentry))); /* osm upload itself also has a gui */ osm_upload_context_t *context = g_new0(osm_upload_context_t, 1); context->appdata = appdata; context->osm = osm; context->project = project; /* add proxy settings if required */ if(appdata->settings) context->proxy = appdata->settings->proxy; /* fetch comment from dialog */ GtkTextIter start, end; gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); char *text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); context->comment = g_strdup(text); gtk_widget_destroy(dialog); project_save(GTK_WIDGET(appdata->window), project); context->dialog = misc_dialog_new(MISC_DIALOG_LARGE,_("Uploading"), GTK_WINDOW(appdata->window), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_response_sensitive(GTK_DIALOG(context->dialog), GTK_RESPONSE_CLOSE, FALSE); /* ------- main ui element is this text view --------------- */ GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); context->log.buffer = gtk_text_buffer_new(NULL); context->log.view = gtk_text_view_new_with_buffer(context->log.buffer); gtk_text_view_set_editable(GTK_TEXT_VIEW(context->log.view), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(context->log.view), FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(context->log.view), GTK_WRAP_WORD); gtk_container_add(GTK_CONTAINER(scrolled_window), context->log.view); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), scrolled_window); gtk_widget_show_all(context->dialog); /* server url should not end with a slash */ if(project->rserver && project->rserver[strlen(project->rserver)-1] == '/') { printf("removing trailing slash\n"); project->rserver[strlen(project->rserver)-1] = 0; } appendf(&context->log, NULL, _("Log generated by %s v%s using API 0.6\n"), PACKAGE, VERSION); appendf(&context->log, NULL, _("User comment: %s\n"), context->comment); /* check if server name contains string "0.5" and adjust it */ if(project->rserver && strstr(project->rserver, "0.5") != NULL) { strstr(project->rserver, "0.5")[2] = '6'; appendf(&context->log, NULL, _("Adjusting server name to v0.6\n")); } appendf(&context->log, NULL, _("Uploading to %s\n"), project->server); /* create a new changeset */ gchar *cred; if(osm_create_changeset(context, &cred)) { /* check for dirty entries */ appendf(&context->log, NULL, _("Uploading nodes:\n")); osm_upload_nodes(context, cred); appendf(&context->log, NULL, _("Uploading ways:\n")); osm_upload_ways(context, cred); appendf(&context->log, NULL, _("Uploading relations:\n")); osm_upload_relations(context, cred); appendf(&context->log, NULL, _("Deleting relations:\n")); osm_delete_relations(context, cred); appendf(&context->log, NULL, _("Deleting ways:\n")); osm_delete_ways(context, cred); appendf(&context->log, NULL, _("Deleting nodes:\n")); osm_delete_nodes(context, cred); /* close changeset */ osm_close_changeset(context, cred); } appendf(&context->log, NULL, _("Upload done.\n")); gboolean reload_map = FALSE; if(project->data_dirty) { appendf(&context->log, NULL, _("Server data has been modified.\n")); appendf(&context->log, NULL, _("Downloading updated osm data ...\n")); if(osm_download(context->dialog, appdata->settings, project)) { appendf(&context->log, NULL, _("Download successful!\n")); appendf(&context->log, NULL, _("The map will be reloaded.\n")); project->data_dirty = FALSE; reload_map = TRUE; } else appendf(&context->log, NULL, _("Download failed!\n")); project_save(context->dialog, project); if(reload_map) { /* this kind of rather brute force reload is useful as the moment */ /* after the upload is a nice moment to bring everything in sync again. */ /* we basically restart the entire map with fresh data from the server */ /* and the diff will hopefully be empty (if the upload was successful) */ appendf(&context->log, NULL, _("Reloading map ...\n")); if(!diff_is_clean(appdata->osm, FALSE)) { appendf(&context->log, COLOR_ERR, _("*** DIFF IS NOT CLEAN ***\n")); appendf(&context->log, COLOR_ERR, _("Something went wrong during upload,\n")); appendf(&context->log, COLOR_ERR, _("proceed with care!\n")); } /* redraw the entire map by destroying all map items and redrawing them */ appendf(&context->log, NULL, _("Cleaning up ...\n")); diff_save(appdata->project, appdata->osm); map_clear(appdata, MAP_LAYER_OBJECTS_ONLY); osm_free(appdata->osm); appendf(&context->log, NULL, _("Loading OSM ...\n")); appdata->osm = osm_parse(appdata->project->path, appdata->project->osm, &appdata->icon); appendf(&context->log, NULL, _("Applying diff ...\n")); diff_restore(appdata, appdata->project, appdata->osm); appendf(&context->log, NULL, _("Painting ...\n")); map_paint(appdata); appendf(&context->log, NULL, _("Done!\n")); } } /* tell the user that he can stop waiting ... */ appendf(&context->log, NULL, _("Process finished.\n")); gtk_dialog_set_response_sensitive(GTK_DIALOG(context->dialog), GTK_RESPONSE_CLOSE, TRUE); gtk_dialog_run(GTK_DIALOG(context->dialog)); gtk_widget_destroy(context->dialog); g_free(context->comment); g_free(context); }
StrBuffer & StrBuffer::append(char c) { appendf("%c",c); return *this; }
/* Dumps the facts table. */ static void dump_facts(MVMThreadContext *tc, DumpStr *ds, MVMSpeshGraph *g) { MVMuint16 i, j, num_locals, num_facts; num_locals = g->num_locals; for (i = 0; i < num_locals; i++) { num_facts = g->fact_counts[i]; for (j = 0; j < num_facts; j++) { MVMint32 flags = g->facts[i][j].flags; MVMSpeshOperand operand; operand.reg.orig = i; operand.reg.i = j; if (i < 10) append(ds, " "); if (j < 10) append(ds, " "); if (flags || g->facts[i][j].dead_writer || (g->facts[i][j].writer && g->facts[i][j].writer->info->opcode == MVM_SSA_PHI)) { appendf(ds, " r%d(%d): usages=%d%s", i, j, MVM_spesh_usages_count(tc, g, operand), MVM_spesh_usages_is_used_by_handler(tc, g, operand) ? "+handler" : ""); dump_deopt_usages(tc, ds, g, operand); appendf(ds, ", flags=%-5d", flags); if (flags & 1) { append(ds, " KnTyp"); } if (flags & 2) { append(ds, " KnVal"); } if (flags & 4) { append(ds, " Dcntd"); } if (flags & 8) { append(ds, " Concr"); } if (flags & 16) { append(ds, " TyObj"); } if (flags & 32) { append(ds, " KnDcT"); } if (flags & 64) { append(ds, " DCncr"); } if (flags & 128) { append(ds, " DcTyO"); } if (flags & 256) { append(ds, " LogGd"); } if (flags & 512) { append(ds, " HashI"); } if (flags & 1024) { append(ds, " ArrIt"); } if (flags & 2048) { append(ds, " KBxSr"); } if (flags & 4096) { append(ds, " MgWLG"); } if (flags & 8192) { append(ds, " KRWCn"); } if (g->facts[i][j].dead_writer) { append(ds, " DeadWriter"); } if (g->facts[i][j].writer && g->facts[i][j].writer->info->opcode == MVM_SSA_PHI) { appendf(ds, " (merged from %d regs)", g->facts[i][j].writer->info->num_operands - 1); } if (flags & 1) { appendf(ds, " (type: %s)", MVM_6model_get_debug_name(tc, g->facts[i][j].type)); } } else { appendf(ds, " r%d(%d): usages=%d%s", i, j, MVM_spesh_usages_count(tc, g, operand), MVM_spesh_usages_is_used_by_handler(tc, g, operand) ? "+handler" : ""); dump_deopt_usages(tc, ds, g, operand); appendf(ds, ", flags=%-5d", flags); } append(ds, "\n"); } append(ds, "\n"); } }