Пример #1
0
  void InlineCacheRegistry::print_stats(STATE) {
    SYNC(state);
    int total = 0;
    std::vector<int> sizes(cTrackedICHits + 1);

    int overflow = 0;

    for(CacheHash::iterator hi = caches_.begin();
        hi != caches_.end();
        ++hi) {
      for(CacheVector::iterator vi = hi->second.begin();
          vi != hi->second.end();
          ++vi) {
        InlineCache* ic = *vi;
        int seen = ic->classes_seen();
        if(ic->seen_classes_overflow() > 0) {
          total++;
          overflow++;
        } else if(seen > 0) {
          total++;
          sizes[seen]++;
        }
      }
    }

    std::cerr << "IC Stats:\n";
    for(int i = 1; i < cTrackedICHits + 1; i++) {
      std::cerr << " " << i << ": " << sizes[i] << " "
                << ratio(sizes[i], total) << "%\n";
    }

    std::cerr << cTrackedICHits << "+: " << overflow << " "
              << ratio(overflow, total) << "%\n";

    // print out the mega-morphic ones
    std::cerr << "\nMegamorphic call sites:\n";

    for(CacheHash::iterator hi = caches_.begin();
        hi != caches_.end();
        ++hi) {
      for(CacheVector::iterator vi = hi->second.begin();
          vi != hi->second.end();
          ++vi) {
        InlineCache* ic = *vi;
        if(ic->seen_classes_overflow() > 0) {
          ic->print(state, std::cerr);
          std::cerr << "location: ";
          ic->print_location(state, std::cerr);
          std::cerr << "\n\n";
        }
      }
    }
  }
Пример #2
0
  void InlineCacheRegistry::print_stats(STATE) {
    int total = 0;
    std::vector<int> sizes(cTrackedICHits + 1);

    int overflow = 0;

    for(CacheHash::iterator hi = caches_.begin();
        hi != caches_.end();
        ++hi) {
      for(CacheVector::iterator vi = hi->second.begin();
          vi != hi->second.end();
          ++vi) {
        InlineCache* ic = *vi;
        int seen = ic->classes_seen();
        if(ic->seen_classes_overflow() > 0) {
          total++;
          overflow++;
        } else if(seen > 0) {
          total++;
          sizes[seen]++;
        }
      }
    }

    std::cerr << "IC Stats:\n";
    for(int i = 1; i < cTrackedICHits + 1; i++) {
      std::cerr << " " << i << ": " << sizes[i] << " "
                << ratio(sizes[i], total) << "%\n";
    }

    std::cerr << cTrackedICHits << "+: " << overflow << " "
              << ratio(overflow, total) << "%\n";

    // Stats that take the number of hits into account
    std::vector<int> hits(cTrackedICHits + 1);
    int overflow_hits = 0;
    int total_hits = 0;

    for(CacheHash::iterator hi = caches_.begin();
        hi != caches_.end();
        ++hi) {
      for(CacheVector::iterator vi = hi->second.begin();
          vi != hi->second.end();
          ++vi) {
        InlineCache* ic = *vi;
        int seen = ic->classes_seen();
        if(ic->seen_classes_overflow() > 0) {
          int these_hits = (ic->total_hits() + ic->seen_classes_overflow());
          overflow_hits += these_hits;
          total_hits += these_hits;
        } else if(seen > 0) {
          hits[seen] += ic->total_hits();
          total_hits += ic->total_hits();
        }
      }
    }

    std::cerr << "Hits per classes tracked: (" << total_hits << ")\n";
    for(int i = 1; i < cTrackedICHits + 1; i++) {
      std::cerr << " " << i << ": " << hits[i] << " "
                << ratio(hits[i], total_hits) << "%\n";
    }

    std::cerr << cTrackedICHits << "+: " << overflow_hits << " "
              << ratio(overflow_hits, total_hits) << "%\n";

    // print out the mega-morphic ones
    std::cerr << "\nMegamorphic call sites:\n";

    for(CacheHash::iterator hi = caches_.begin();
        hi != caches_.end();
        ++hi) {
      for(CacheVector::iterator vi = hi->second.begin();
          vi != hi->second.end();
          ++vi) {
        InlineCache* ic = *vi;
        if(ic->seen_classes_overflow() > 0) {
          ic->print(state, std::cerr);
          std::cerr << "location: ";
          ic->print_location(state, std::cerr);
          std::cerr << "\n\n";
        }
      }
    }
  }
Пример #3
0
  void MachineCode::initialize_caches(STATE, CompiledCode* original, int sends) {
    number_of_caches_ = sends;
    caches = new InlineCache[sends];

    int which = 0;
    bool allow_private = false;
    bool is_super = false;

    for(size_t ip = 0; ip < total;) {
      opcode op = opcodes[ip];
      switch(op) {
      case InstructionSequence::insn_invoke_primitive: {
        Symbol* name = try_as<Symbol>(original->literals()->at(opcodes[ip + 1]));
        if(!name) {
          name = state->symbol("__unknown__");
        }

        InvokePrimitive invoker = Primitives::get_invoke_stub(state, name);
        opcodes[ip + 1] = reinterpret_cast<intptr_t>(invoker);
        update_addresses(ip, 1);
        break;
      }
      case InstructionSequence::insn_allow_private:
        allow_private = true;
        break;
      case InstructionSequence::insn_push_const_fast:
      case InstructionSequence::insn_find_const_fast:
        original->literals()->put(state, opcodes[ip + 2], GlobalCacheEntry::empty(state));
        break;
      case InstructionSequence::insn_send_super_stack_with_block:
      case InstructionSequence::insn_send_super_stack_with_splat:
      case InstructionSequence::insn_zsuper:
        is_super = true;
        // fall through
      case InstructionSequence::insn_check_serial:
      case InstructionSequence::insn_check_serial_private:
      case InstructionSequence::insn_call_custom:
      case InstructionSequence::insn_send_method:
      case InstructionSequence::insn_send_stack:
      case InstructionSequence::insn_send_stack_with_block:
      case InstructionSequence::insn_send_stack_with_splat:
      case InstructionSequence::insn_meta_send_call:
      case InstructionSequence::insn_meta_send_op_plus:
      case InstructionSequence::insn_meta_send_op_minus:
      case InstructionSequence::insn_meta_send_op_equal:
      case InstructionSequence::insn_meta_send_op_tequal:
      case InstructionSequence::insn_meta_send_op_lt:
      case InstructionSequence::insn_meta_send_op_gt:
      case InstructionSequence::insn_meta_to_s:
        {
        assert(which < sends);
        InlineCache* cache = &caches[which++];
        cache->set_location(ip, this);

        Symbol* name = try_as<Symbol>(original->literals()->at(opcodes[ip + 1]));
        if(!name) {
          name = state->symbol("__unknown__");
        }

        cache->set_name(name);

        if(op == InstructionSequence::insn_call_custom) {
          cache->set_call_custom();
        } else {
          if(allow_private) cache->set_is_private();
          if(is_super) cache->set_is_super();

          if(op == InstructionSequence::insn_send_method) {
            cache->set_is_vcall();
          }
        }

        state->shared().ic_registry()->add_cache(state, name, cache);

        opcodes[ip + 1] = reinterpret_cast<intptr_t>(cache);
        update_addresses(ip, 1);

        is_super = false;
        allow_private = false;
      }
      }

      ip += InstructionSequence::instruction_width(op);
    }
  }