int align_read(const fm_index *fmi, const char *seq, const char *pattern, int len, int thresh) { int starts[10], lens[10], nsegments; int penalty; int nmisses = len/10; int olen = len; for (nsegments = 0; nsegments < 10; nsegments++) { if (len < 10) break; int start, end; int seglen = mms(fmi, pattern, len, &start, &end); if (seglen < thresh) { int mlen = mms_mismatch(fmi, seq, pattern, len - seglen, &start, &end, &penalty); if (mlen + seglen > 2 * thresh) { len -= seglen + mlen + 3; starts[nsegments] = start; lens[nsegments] = seglen + mlen; continue; } if (!nmisses--) return 0; len -= 3; nsegments--; if (nsegments > -1) { starts[nsegments] -= 3; lens[nsegments] += 3; } continue; } if ((len - seglen == 0) || ((len - seglen > 10) && end - start == 1)) { starts[nsegments] = start; lens[nsegments] = seglen; len -= seglen + 3; continue; } // Otherwise try continuing the search int mlen = mms_mismatch(fmi, seq, pattern, len - seglen, &start, &end, &penalty); len -= seglen + mlen + 3; starts[nsegments] = start; lens[nsegments] = seglen + mlen; } int totlen = lens[0]; if (nsegments == 10) return 0; // Too many segments else { // For each segment check whether it's within 6 nts of the next for (int i = 0; i < nsegments - 1; ++i) { if (abs(unc_sa(fmi, starts[i+1]) + lens[i+1] - unc_sa(fmi, starts[i])) < 7) { totlen += lens[i+1]; continue; } else return 0; // Gapped } } if (3 * totlen > 2 * olen) return unc_sa(fmi, starts[nsegments-1]) - len; return 0; }
int main() { remove("asio_mmstore.mms"); boost::asio::io_service io_service; mmstore mms(io_service, "10240", "2", "asio_mmstore.mms"); mms.create("tmp.file"); reader r(mms); writer w(mms); io_service.run(); return 0; }
int main() { { boost::asio::io_service io_service; remove("mmstore_serialize.mms"); mmstore mms(io_service, "10240", "2", "mmstore_serialize.mms"); mms.create("serialize_test"); writer w(mms); io_service.run(); // trigger serialization } { boost::asio::io_service io_service; mmstore mms(io_service, "10240", "2", "mmstore_serialize.mms"); reader r(mms); io_service.run(); // trigger deserialization } return 0; }
JVMState* PredicatedIntrinsicGenerator::generate(JVMState* jvms) { // The code we want to generate here is: // if (receiver == NULL) // uncommon_Trap // if (predicate(0)) // do_intrinsic(0) // else // if (predicate(1)) // do_intrinsic(1) // ... // else // do_java_comp GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); CompileLog* log = kit.C->log(); if (log != NULL) { log->elem("predicated_intrinsic bci='%d' method='%d'", jvms->bci(), log->identify(method())); } if (!method()->is_static()) { // We need an explicit receiver null_check before checking its type in predicate. // We share a map with the caller, so his JVMS gets adjusted. Node* receiver = kit.null_check_receiver_before_call(method()); if (kit.stopped()) { return kit.transfer_exceptions_into_jvms(); } } int n_predicates = _intrinsic->predicates_count(); assert(n_predicates > 0, "sanity"); JVMState** result_jvms = NEW_RESOURCE_ARRAY(JVMState*, (n_predicates+1)); // Region for normal compilation code if intrinsic failed. Node* slow_region = new (kit.C) RegionNode(1); int results = 0; for (int predicate = 0; (predicate < n_predicates) && !kit.stopped(); predicate++) { #ifdef ASSERT JVMState* old_jvms = kit.jvms(); SafePointNode* old_map = kit.map(); Node* old_io = old_map->i_o(); Node* old_mem = old_map->memory(); Node* old_exc = old_map->next_exception(); #endif Node* else_ctrl = _intrinsic->generate_predicate(kit.sync_jvms(), predicate); #ifdef ASSERT // Assert(no_new_memory && no_new_io && no_new_exceptions) after generate_predicate. assert(old_jvms == kit.jvms(), "generate_predicate should not change jvm state"); SafePointNode* new_map = kit.map(); assert(old_io == new_map->i_o(), "generate_predicate should not change i_o"); assert(old_mem == new_map->memory(), "generate_predicate should not change memory"); assert(old_exc == new_map->next_exception(), "generate_predicate should not add exceptions"); #endif if (!kit.stopped()) { PreserveJVMState pjvms(&kit); // Generate intrinsic code: JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms()); if (new_jvms == NULL) { // Intrinsic failed, use normal compilation path for this predicate. slow_region->add_req(kit.control()); } else { kit.add_exception_states_from(new_jvms); kit.set_jvms(new_jvms); if (!kit.stopped()) { result_jvms[results++] = kit.jvms(); } } } if (else_ctrl == NULL) { else_ctrl = kit.C->top(); } kit.set_control(else_ctrl); } if (!kit.stopped()) { // Final 'else' after predicates. slow_region->add_req(kit.control()); } if (slow_region->req() > 1) { PreserveJVMState pjvms(&kit); // Generate normal compilation code: kit.set_control(gvn.transform(slow_region)); JVMState* new_jvms = _cg->generate(kit.sync_jvms()); if (kit.failing()) return NULL; // might happen because of NodeCountInliningCutoff assert(new_jvms != NULL, "must be"); kit.add_exception_states_from(new_jvms); kit.set_jvms(new_jvms); if (!kit.stopped()) { result_jvms[results++] = kit.jvms(); } } if (results == 0) { // All paths ended in uncommon traps. (void) kit.stop(); return kit.transfer_exceptions_into_jvms(); } if (results == 1) { // Only one path kit.set_jvms(result_jvms[0]); return kit.transfer_exceptions_into_jvms(); } // Merge all paths. kit.C->set_has_split_ifs(true); // Has chance for split-if optimization RegionNode* region = new (kit.C) RegionNode(results + 1); Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); for (int i = 0; i < results; i++) { JVMState* jvms = result_jvms[i]; int path = i + 1; SafePointNode* map = jvms->map(); region->init_req(path, map->control()); iophi->set_req(path, map->i_o()); if (i == 0) { kit.set_jvms(jvms); } else { kit.merge_memory(map->merged_memory(), region, path); } } kit.set_control(gvn.transform(region)); kit.set_i_o(gvn.transform(iophi)); // Transform new memory Phis. for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) { Node* phi = mms.memory(); if (phi->is_Phi() && phi->in(0) == region) { mms.set_memory(gvn.transform(phi)); } } // Merge debug info. Node** ins = NEW_RESOURCE_ARRAY(Node*, results); uint tos = kit.jvms()->stkoff() + kit.sp(); Node* map = kit.map(); uint limit = map->req(); for (uint i = TypeFunc::Parms; i < limit; i++) { // Skip unused stack slots; fast forward to monoff(); if (i == tos) { i = kit.jvms()->monoff(); if( i >= limit ) break; } Node* n = map->in(i); ins[0] = n; const Type* t = gvn.type(n); bool needs_phi = false; for (int j = 1; j < results; j++) { JVMState* jvms = result_jvms[j]; Node* jmap = jvms->map(); Node* m = NULL; if (jmap->req() > i) { m = jmap->in(i); if (m != n) { needs_phi = true; t = t->meet_speculative(gvn.type(m)); } } ins[j] = m; } if (needs_phi) { Node* phi = PhiNode::make(region, n, t); for (int j = 1; j < results; j++) { phi->set_req(j + 1, ins[j]); } map->set_req(i, gvn.transform(phi)); } } return kit.transfer_exceptions_into_jvms(); }
JVMState* PredictedCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); // We need an explicit receiver null_check before checking its type. // We share a map with the caller, so his JVMS gets adjusted. Node* receiver = kit.argument(0); CompileLog* log = kit.C->log(); if (log != NULL) { log->elem("predicted_call bci='%d' klass='%d'", jvms->bci(), log->identify(_predicted_receiver)); } receiver = kit.null_check_receiver_before_call(method()); if (kit.stopped()) { return kit.transfer_exceptions_into_jvms(); } // Make a copy of the replaced nodes in case we need to restore them ReplacedNodes replaced_nodes = kit.map()->replaced_nodes(); replaced_nodes.clone(); Node* exact_receiver = receiver; // will get updated in place... Node* slow_ctl = kit.type_check_receiver(receiver, _predicted_receiver, _hit_prob, &exact_receiver); SafePointNode* slow_map = NULL; JVMState* slow_jvms = NULL; { PreserveJVMState pjvms(&kit); kit.set_control(slow_ctl); if (!kit.stopped()) { slow_jvms = _if_missed->generate(kit.sync_jvms()); if (kit.failing()) return NULL; // might happen because of NodeCountInliningCutoff assert(slow_jvms != NULL, "must be"); kit.add_exception_states_from(slow_jvms); kit.set_map(slow_jvms->map()); if (!kit.stopped()) slow_map = kit.stop(); } } if (kit.stopped()) { // Instance exactly does not matches the desired type. kit.set_jvms(slow_jvms); return kit.transfer_exceptions_into_jvms(); } // fall through if the instance exactly matches the desired type kit.replace_in_map(receiver, exact_receiver); // Make the hot call: JVMState* new_jvms = _if_hit->generate(kit.sync_jvms()); if (new_jvms == NULL) { // Inline failed, so make a direct call. assert(_if_hit->is_inline(), "must have been a failed inline"); CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method()); new_jvms = cg->generate(kit.sync_jvms()); } kit.add_exception_states_from(new_jvms); kit.set_jvms(new_jvms); // Need to merge slow and fast? if (slow_map == NULL) { // The fast path is the only path remaining. return kit.transfer_exceptions_into_jvms(); } if (kit.stopped()) { // Inlined method threw an exception, so it's just the slow path after all. kit.set_jvms(slow_jvms); return kit.transfer_exceptions_into_jvms(); } // There are 2 branches and the replaced nodes are only valid on // one: restore the replaced nodes to what they were before the // branch. kit.map()->set_replaced_nodes(replaced_nodes); // Finish the diamond. kit.C->set_has_split_ifs(true); // Has chance for split-if optimization RegionNode* region = new (kit.C) RegionNode(3); region->init_req(1, kit.control()); region->init_req(2, slow_map->control()); kit.set_control(gvn.transform(region)); Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO); iophi->set_req(2, slow_map->i_o()); kit.set_i_o(gvn.transform(iophi)); // Merge memory kit.merge_memory(slow_map->merged_memory(), region, 2); // Transform new memory Phis. for (MergeMemStream mms(kit.merged_memory()); mms.next_non_empty();) { Node* phi = mms.memory(); if (phi->is_Phi() && phi->in(0) == region) { mms.set_memory(gvn.transform(phi)); } } uint tos = kit.jvms()->stkoff() + kit.sp(); uint limit = slow_map->req(); for (uint i = TypeFunc::Parms; i < limit; i++) { // Skip unused stack slots; fast forward to monoff(); if (i == tos) { i = kit.jvms()->monoff(); if( i >= limit ) break; } Node* m = kit.map()->in(i); Node* n = slow_map->in(i); if (m != n) { const Type* t = gvn.type(m)->meet_speculative(gvn.type(n)); Node* phi = PhiNode::make(region, m, t); phi->set_req(2, n); kit.map()->set_req(i, gvn.transform(phi)); } } return kit.transfer_exceptions_into_jvms(); }
// Pass in the required anchor length. No mismatch will be allowed. int align_read_anchored(const fm_index *fmi, const char *seq, const char *pattern, int len, int anchor_len, stack *s) { const int olen = len; int anchmisses = len/10, nmisses; // Here we require an anchor to start in the last 20% of the read int curgap = 0; int curpos = -1; int endpos; int anchlen; // Look for an anchor of length at least anchor_len (try 20 or so, or maybe // log_4(fmi->len)+1) while (len > anchor_len && anchmisses > 0) { nmisses = 0; while ((len > anchor_len) && (anchmisses > 0)) { int seglen = mms(fmi, pattern, len, &curpos, &endpos); if (seglen < anchor_len || endpos - curpos > 1) { anchmisses--; len -= 3; continue; } else { len -= seglen; anchlen = seglen; nmisses = olen/5; curpos = unc_sa(fmi, curpos); //fprintf(stderr, "%d %d %d\n", anchlen, olen, len); // And use N-W to align the "tail" of the read int buflen = 10 + (olen - (len + seglen)); if (buflen + curpos + seglen > fmi->len) buflen = fmi->len - curpos - seglen; char *buf = malloc(buflen); for (int i = 0; i < buflen; ++i) buf[i] = getbase(seq, curpos + seglen + i); nw_fast(pattern + len + seglen, olen - (len + seglen), buf, buflen, s); // We can ignore the return value (we don't really care where the // end of the read ends up; we can calculate that from the CIGAR) free(buf); // free(buf2); // Then push this anchor onto it stack_push(s, 'M', seglen); break; } } if (nmisses < 1) continue; // In the second loop we try to extend our anchor backwards while ((len > nmisses) && (len > 4) && (nmisses > 0)) { for (curgap = 1; curgap < 10; ++curgap) { int start, end; int seglen = mms(fmi, pattern, len-curgap, &start, &end); int matched = 0; for (int i = start; i < end; ++i) { if (abs(unc_sa(fmi, i) + seglen - curpos) - curgap <= 3) { // TODO: write proper scoring function, the number of misses // is not going to be curgap. nmisses -= curgap; matched = 1; // Align the stuff in between. In this case we don't need to // copy pattern to a new buffer, but we do still need to copy // the genome int buflen = curpos - (unc_sa(fmi, i) + seglen); // There's a semi-theoretical problem that this might actually // be negative, but that's easy to resolve if (buflen < 0) { stack_push(s, 'I', -buflen); } else { char *buf = malloc(buflen); for (int j = 0; j < buflen; ++j) buf[j] = getbase(seq, unc_sa(fmi, i) + seglen + j); // And compare sw_fast(pattern + (len - curgap), curgap, buf, buflen, s); free(buf); } stack_push(s, 'M', seglen); curpos = unc_sa(fmi, i); len -= seglen + curgap; curgap = 0; break; } } if (matched) break; else continue; } if (curgap) nmisses = 0; } if (nmisses > 0) { // Set up matrix for N-W alignment int buflen = len + 10; if (buflen > curpos) buflen = curpos; char *buf = malloc(buflen); for (int i = 0; i < buflen; ++i) buf[i] = getbase(seq, curpos - 1 - i); char *buf2 = malloc(len); for (int i = 0; i < len; ++i) buf2[i] = pattern[len-1-i]; int x = nw_fast(buf2, len, buf, buflen, s); free(buf); free(buf2); //printf("%d %d\t", x, len); return curpos - x; } len -= anchlen; anchmisses -= anchlen / 10; //stack_destroy(s); //s = stack_make(); // reset the stack s->size = 0; } if (len > nmisses || nmisses < 1) { return 0; } int buflen = len + 10; if (buflen > curpos) buflen = curpos; char *buf = malloc(buflen); for (int i = 0; i < buflen; ++i) buf[i] = getbase(seq, curpos - 1 - i); char *buf2 = malloc(len); for (int i = 0; i < len; ++i) buf2[i] = pattern[len-1-i]; int x = nw_fast(buf2, len, buf, buflen, s); free(buf); free(buf2); return curpos - len; }