bool Full(int index) const { if (_in_range(index)) { return _stacks[index].full(); } throw std::out_of_range("Given index is out of range."); }
_Ty Peek(int index) const { if (_in_range(index)) { return _stacks[index].peek(); } throw std::out_of_range("Given index is out of range."); }
void Pop(int index) { if (_in_range(index)) { _stacks[index].pop(); return; } throw std::out_of_range("Given index is out of range."); }
void Push(int index, _Ty val) { if (_in_range(index)) { _stacks[index].push(val); return; } throw std::out_of_range("Given index is out of range."); }
void __hidden get_dvm_backtrace(struct tls_info *tls, struct dvm_iface *dvm, struct bt_state *bt_state, struct dvm_bt *dvm_bt) { int cnt; if (!dvm->valid || !tls) return; dvm_bt->count = 0; /* * Search through the native backtrace for the java stack indicators. * It should be faster to search up from the bottom of the stack * because the dvmCallMethod function is generally invoked from * platform-specific assembly quite early in the backtrace. */ cnt = bt_state->count; while (--cnt >= 0) { int ii; void *addr = bt_state->frame[cnt].pc; for (ii = 0; ii < (int)ARRAY_SZ(dvm->dvmCallMethodSym); ii++) if (_in_range(addr, dvm->dvmCallMethodSym[ii])) goto do_dvm_bt; } return; /* * We have a call stack that's from a Java/Dalvik thread: * get the backtrace! */ do_dvm_bt: { struct Thread *self; uint32_t *fp = NULL; char *tname; struct Method **mlist; int r; self = dvm->dvmThreadSelf(); if (!self) return; fp = self->interpSave.curFrame; if (!fp) return; /* * There is a bug in dvmGetThreadName() that causes this * to crash when we call it before the thread has a * Java/Dalvik name, but after a Java function has been * invoked. This happens primarily at system boot... tname = tls->dvm_threadname; if (!tname[0]) { int len; std::string nm = dvm->dvmGetThreadName(self); len = nm.length(); if (len >= TLS_MAX_STRING_LEN) len = TLS_MAX_STRING_LEN - 1; libc.memcpy(tname, nm.c_str(), len); libc_log("I:DalvikThreadName:%s:", tname); } */ mlist = dvm_bt->mlist; dvm_bt->count = dvm->dvmComputeExactFrameDepth(fp); if (dvm_bt->count > MAX_BT_FRAMES) { /* * we need an array big enough for this frame * because the dvm fill stack array function * doesn't care how big our array really is... */ mlist = libc.malloc((dvm_bt->count + 1) * sizeof(struct Method *)); if (!mlist) { dvm_bt->count = 0; return; } dvm_bt->count = MAX_BT_FRAMES; } /* * Grrr. This API doesn't respect the 'length' parameter. * It just sends out an error message (if you're lucky enough * to have copiled without NDEBUG), and continues to mash on * your memory even though it's out of bounds... */ dvm->dvmFillStackTraceArray(fp, mlist, dvm_bt->count); if (mlist != dvm_bt->mlist) { /* copy only the portion of data back that fits */ libc.memcpy(dvm_bt->mlist, mlist, dvm_bt->count * sizeof(struct Method *)); libc.free(mlist); } } return; }
/* * FIXME - It would be nice to parse the multi-prog array just once * to retrieve the argv arrays for each task on this node, rather * than calling multi_prog_get_argv once for each task. */ extern int multi_prog_get_argv(char *config_data, char **prog_env, int task_rank, uint32_t *argc, char ***argv, int global_argc, char **global_argv) { char *line = NULL; int i, line_num = 0; int task_offset; char *p = NULL, *ptrptr = NULL; char *rank_spec = NULL, *args_spec = NULL; int prog_argc = 0; char **prog_argv = NULL; char *local_data = NULL; size_t tmp_buf_len = 256; char tmp_buf[tmp_buf_len]; char *arg_buf = NULL; bool last_line_break = false, line_break = false; int line_len; prog_argv = (char **)xmalloc(sizeof(char *) * MAX_ARGC); if (task_rank < 0) { error("Invalid task rank %d", task_rank); *argc = 1; *argv = prog_argv; return -1; } local_data = xstrdup(config_data); line = strtok_r(local_data, "\n", &ptrptr); while (line) { if (line_num > 0) line = strtok_r(NULL, "\n", &ptrptr); if (line == NULL) { error("No executable program specified for this task"); goto fail; } line_num++; line_len = strlen(line); if ((line_len > 0) && (line[line_len - 1] == '\\')) line_break = true; else line_break = false; if (last_line_break) { last_line_break = line_break; continue; } last_line_break = line_break; p = line; while ((*p != '\0') && isspace (*p)) /* remove leading spaces */ p++; if (*p == '#') /* only whole-line comments handled */ continue; if (*p == '\0') /* blank line ignored */ continue; rank_spec = p; while ((*p != '\0') && !isspace (*p)) p++; if (*p == '\0') { error("Invalid MPMD configuration line %d", line_num); goto fail; } *p++ = '\0'; if (!_in_range(task_rank, rank_spec, &task_offset)) continue; /* skip all whitspace after the range spec */ while ((*p != '\0') && isspace (*p)) p++; args_spec = p; while (*args_spec != '\0') { /* Only simple quote and escape supported */ if (arg_buf) { prog_argv[prog_argc++] = arg_buf; arg_buf=NULL; } if ((prog_argc + 1) >= MAX_ARGC) { info("Exceeded multi-prog argc limit"); break; } CONT: p = args_spec; while ((*args_spec != '\0') && (*args_spec != '\\') && (*args_spec != '%') && (*args_spec != '\'') && !isspace(*args_spec)) { args_spec++; } xstrncat(arg_buf, p, (args_spec - p)); if (*args_spec == '\0') { /* the last argument */ break; } else if (*args_spec == '%') { args_spec++; if (*args_spec == 't') { /* task rank */ snprintf(tmp_buf, tmp_buf_len, "%d", task_rank); xstrcat(arg_buf, tmp_buf); } else if (*args_spec == 'o') { /* task offset */ snprintf(tmp_buf, tmp_buf_len, "%d", task_offset); xstrcat(arg_buf, tmp_buf); } args_spec++; goto CONT; } else if (*args_spec == '\\') { /* escape, just remove the backslash */ args_spec++; if (*args_spec != '\0') { xstrcatchar(arg_buf, *args_spec); args_spec++; } else { line = strtok_r(NULL, "\n", &ptrptr); if (!line) break; line_num++; args_spec = line; } goto CONT; } else if (*args_spec == '\'') { /* single quote, * preserve all characters quoted. */ p = ++args_spec; LINE_BREAK: while ((*args_spec != '\0') && (*args_spec != '\'')) { args_spec++; } if (*args_spec == '\0') { /* closing quote not found */ if (*(args_spec - 1) == '\\') { line = strtok_r(NULL, "\n", &ptrptr); if (line) { line_num++; args_spec = line; goto LINE_BREAK; } } error("Program arguments specification format invalid: %s.", prog_argv[prog_argc - 1]); goto fail; } xstrncat(arg_buf, p, (args_spec - p)); args_spec++; goto CONT; } else { /* space */ while ((*args_spec != '\0') && isspace(*args_spec)) { args_spec++; } } } if (arg_buf) { prog_argv[prog_argc++] = arg_buf; arg_buf = NULL; } for (i = 2; i < global_argc; i++) { if ((prog_argc + 1) >= MAX_ARGC) { info("Exceeded multi-prog argc limit"); break; } prog_argv[prog_argc++] = xstrdup(global_argv[i]); } prog_argv[prog_argc] = NULL; *argc = prog_argc; *argv = prog_argv; xfree(local_data); return 0; } error("Program for task rank %d not specified.", task_rank); fail: xfree(local_data); *argc = 1; prog_argv[0] = NULL; *argv = prog_argv; return -1; }