Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 100 lines (82 sloc) 2.467 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#ifndef RBX_VM_GLOBAL_CACHE_HPP
#define RBX_VM_GLOBAL_CACHE_HPP

#include "vm/object_utils.hpp"

#include "builtin/compiledmethod.hpp"
#include "builtin/methodvisibility.hpp"

namespace rubinius {
#define CPU_CACHE_SIZE 0x1000
#define CPU_CACHE_MASK 0xfff
#define CPU_CACHE_HASH(c,m) ((((uintptr_t)(c)>>3)^((uintptr_t)m)) & CPU_CACHE_MASK)

  class GlobalCache {
  public:
    struct cache_entry {
      Module* klass;
      SYMBOL name;
      Module* module;
      Executable* method;
      bool is_public;
      bool method_missing;
    };

    struct cache_entry entries[CPU_CACHE_SIZE];

    GlobalCache() {
      clear();
    }

    struct cache_entry* lookup(Module* cls, SYMBOL name) {
      struct cache_entry* entry;

      entry = entries + CPU_CACHE_HASH(cls, name);
      if(entry->name == name && entry->klass == cls) {
        return entry;
      }

      return NULL;
    }

    void clear() {
      for(size_t i = 0; i < CPU_CACHE_SIZE; i++) {
        entries[i].klass = 0;
        entries[i].name = 0;
        entries[i].module = 0;
        entries[i].method = 0;
        entries[i].is_public = true;
        entries[i].method_missing = false;
      }
    }

    void clear(SYMBOL name) {
      for(size_t i = 0; i < CPU_CACHE_SIZE; i++) {
        if(entries[i].name == name) {
          entries[i].klass = NULL;
          entries[i].name = NULL;
          entries[i].module = NULL;
          entries[i].method = NULL;
          entries[i].method_missing = false;
        }
      }
    }

    void clear(Module* cls, SYMBOL name) {
      struct cache_entry* entry;

      entry = entries + CPU_CACHE_HASH(cls, name);
      if(entry->name == name && entry->klass == cls) {
        entry->klass = NULL;
        entry->name = NULL;
        entry->module = NULL;
        entry->method = NULL;
        entry->method_missing = false;
      }
    }

    void retain(STATE, Module* cls, SYMBOL name, Module* mod, Executable* meth, bool missing) {
      struct cache_entry* entry;

      entry = entries + CPU_CACHE_HASH(cls, name);
      entry->klass = cls;
      entry->name = name;
      entry->module = mod;
      entry->method_missing = missing;

      if(kind_of<MethodVisibility>(meth)) {
        MethodVisibility* vis = as<MethodVisibility>(meth);
        entry->is_public = vis->public_p(state);
        entry->method = vis->method();
      } else {
        entry->method = meth;
        entry->is_public = true;
      }
    }
  };
};

#endif
Something went wrong with that request. Please try again.