Skip to content

Commit

Permalink
Fix inline cache. Closes #3783.
Browse files Browse the repository at this point in the history
  • Loading branch information
brixen committed Feb 9, 2018
1 parent fe8597f commit 985ac9e
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 117 deletions.
2 changes: 2 additions & 0 deletions core/call_site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,7 @@ def inspect

str << ">"
end

alias_method :to_s, :inspect
end
end
12 changes: 0 additions & 12 deletions core/prediction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,4 @@ def valid?
raise PrimitiveFailure, "Prediction#valid? primitive failed"
end
end

class MethodPrediction < Prediction
attr_reader :module
attr_reader :executable

def inspect
"#<#{self.class.name}:0x#{object_id.to_s(16)} valid=#{valid?}" \
" module=#{@module} executable=#{@executable}>"
end

alias_method :to_s, :inspect
end
end
26 changes: 20 additions & 6 deletions machine/class/call_site.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ namespace rubinius {
for(int i = 0; i < cache->size(); i++) {
Cache::Entry* entry = cache->entries(i);

Tuple* t = Tuple::from(state, 8,
Tuple* t = Tuple::from(state, 12,
state->symbol("receiver"),
entry->receiver_class()->module_name(),
state->symbol("prediction"),
entry->prediction(),
state->symbol("module"),
entry->module(),
state->symbol("executable"),
entry->executable(),
state->symbol("hits"),
Integer::from(state, entry->hits()),
state->symbol("misses"),
Expand Down Expand Up @@ -74,7 +78,7 @@ namespace rubinius {
// Disable if call site is unstable for caching
if(cache->evictions() > max_evictions) {
call_site->set_cache(nullptr);
call_site->execute(CallSite::dispatch);
call_site->executor(CallSite::dispatch);

call_site->delete_cache(cache);

Expand All @@ -90,7 +94,7 @@ namespace rubinius {
if(new_cache) {
vm->metrics()->inline_cache_count++;
} else {
call_site->execute(CallSite::dispatch_once);
call_site->executor(CallSite::dispatch_once);
}
}
}
Expand All @@ -111,16 +115,26 @@ namespace rubinius {
}

if(Object* ref = mark.call(entry->prediction())) {
entry->prediction(as<MethodPrediction>(ref));
entry->prediction(as<Prediction>(ref));
mark.just_set(call_site, ref);
}

if(Object* ref = mark.call(entry->module())) {
entry->module(as<Module>(ref));
mark.just_set(call_site, ref);
}

if(Object* ref = mark.call(entry->executable())) {
entry->executable(as<Executable>(ref));
mark.just_set(call_site, ref);
}

if(vm->shared.profiler()->collecting_p()) {
if(CompiledCode* code = try_as<CompiledCode>(entry->prediction()->executable())) {
if(CompiledCode* code = try_as<CompiledCode>(entry->executable())) {
if(code->machine_code()->sample_count > vm->shared.profiler()->sample_min()) {
vm->shared.profiler()->add_entry(call_site->serial(), call_site->ip(),
code->machine_code()->serial(), entry->hits(),
entry->receiver_class()->name(), entry->prediction()->module()->name());
entry->receiver_class()->name(), entry->module()->name());
}
}
}
Expand Down
48 changes: 24 additions & 24 deletions machine/class/call_site.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ namespace rubinius {
attr_field(hits, uint32_t);
attr_field(misses, uint32_t);
attr_field(receiver_class, Class*);
attr_field(prediction, MethodPrediction*);
attr_field(prediction, Prediction*);
attr_field(module, Module*);
attr_field(executable, Executable*);

Entry(Class* receiver, MethodPrediction* prediction)
Entry(Class* receiver, Dispatch& dispatch)
: _hits_(1)
, _misses_(0)
, _receiver_class_(receiver)
, _prediction_(prediction)
, _prediction_(dispatch.prediction)
, _module_(dispatch.module)
, _executable_(dispatch.method)
{
}

Expand Down Expand Up @@ -82,7 +86,7 @@ namespace rubinius {
uint8_t* mem = new uint8_t[sizeof(Cache) + sizeof(Entry)];

Cache* new_cache = new(mem) Cache(1);
new(new_cache->_entries_) Entry(receiver, dispatch.prediction);
new(new_cache->_entries_) Entry(receiver, dispatch);

state->vm()->metrics()->inline_cache_count++;

Expand All @@ -101,7 +105,7 @@ namespace rubinius {
uint8_t* mem = new uint8_t[sizeof(Cache) + (size * sizeof(Entry))];

Cache* new_cache = new(mem) Cache(size, cache);
new(new_cache->_entries_) Entry(receiver, dispatch.prediction);
new(new_cache->_entries_) Entry(receiver, dispatch);

new_cache->copy_valid(cache, 1);

Expand Down Expand Up @@ -203,9 +207,8 @@ namespace rubinius {
cache->hit();
entry->hit();

return entry->prediction()->executable()->execute(state,
entry->prediction()->executable(),
entry->prediction()->module(), args);
return entry->executable()->execute(state,
entry->executable(), entry->module(), args);
}

cache->miss();
Expand All @@ -228,9 +231,8 @@ namespace rubinius {
cache->hit();
entries[i].hit();

return entries[i].prediction()->executable()->execute(state,
entries[i].prediction()->executable(),
entries[i].prediction()->module(), args);
return entries[i].executable()->execute(state,
entries[i].executable(), entries[i].module(), args);
} else {
entries[i].miss();
}
Expand Down Expand Up @@ -261,7 +263,7 @@ namespace rubinius {
attr_field(rotations, int);
attr_field(kind, MethodMissingReason);

attr_field(execute, Executor);
attr_field(executor, Executor);

std::list<Cache*>* _dead_list_;
locks::spinlock_mutex _dead_list_mutex_;
Expand All @@ -276,7 +278,7 @@ namespace rubinius {
obj->invokes(0);
obj->rotations(0);
obj->kind(eNone);
obj->execute(CallSite::dispatch_once);
obj->executor(CallSite::dispatch_once);

obj->_dead_list_ = nullptr;
obj->_dead_list_mutex_.unlock();
Expand Down Expand Up @@ -318,7 +320,7 @@ namespace rubinius {
}

Object* execute(STATE, Arguments& args) {
return _execute_(state, this, args);
return executor()(state, this, args);
}

void lookup(STATE, Arguments& args, Dispatch& dispatch, LookupData& lookup_data) {
Expand Down Expand Up @@ -386,9 +388,9 @@ namespace rubinius {
dead_cache(cache);

if(new_cache->size() == 1) {
execute(Cache::mono_execute);
executor(Cache::mono_execute);
} else {
execute(Cache::poly_execute);
executor(Cache::poly_execute);
}

std::atomic_thread_fence(std::memory_order_seq_cst);
Expand All @@ -400,7 +402,7 @@ namespace rubinius {
Cache::create(state, receiver, dispatch);

if(_cache_.compare_exchange_strong(cache, new_cache)) {
execute(Cache::mono_execute);
executor(Cache::mono_execute);

std::atomic_thread_fence(std::memory_order_seq_cst);
} else {
Expand All @@ -419,7 +421,7 @@ namespace rubinius {
uint64_t receiver = reinterpret_cast<uint64_t>(entry->receiver_class());

if(((entry->prediction()->valid() & receiver) == klass)
&& (entry->prediction()->executable()->serial()->to_native() == serial))
&& (entry->executable()->serial()->to_native() == serial))
{
return true;
}
Expand Down Expand Up @@ -465,9 +467,7 @@ namespace rubinius {
if((value = dispatch.method->execute(state, dispatch.method, dispatch.module, args))) {
if(dispatch.name == G(sym_method_missing)) return value;

if(call_site->execute() == CallSite::dispatch_and_cache) {
call_site->cache_method(state, args.recv()->direct_class(state), dispatch);
}
call_site->cache_method(state, args.recv()->direct_class(state), dispatch);
}

return value;
Expand All @@ -486,8 +486,8 @@ namespace rubinius {
if((value = dispatch.method->execute(state, dispatch.method, dispatch.module, args))) {
if(dispatch.name == G(sym_method_missing)) return value;

if(call_site->execute() == CallSite::dispatch_once) {
call_site->execute(CallSite::dispatch_and_cache);
if(call_site->executor() == CallSite::dispatch_once) {
call_site->executor(CallSite::dispatch_and_cache);
}
}

Expand Down Expand Up @@ -596,7 +596,7 @@ namespace rubinius {
// Rubinius.primitive :call_site_reset
CallSite* reset(STATE) {
invokes(0);
execute(CallSite::dispatch_once);
executor(CallSite::dispatch_once);

if(Cache* cache = this->cache()) {
delete_cache(cache);
Expand Down
6 changes: 3 additions & 3 deletions machine/class/method_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ namespace rubinius {
if(!entry->prediction()->nil_p()) {
entry->prediction()->invalidate();
}
entry->prediction(state, nil<MethodPrediction>());
entry->prediction(state, nil<Prediction>());
return name;
}

Expand Down Expand Up @@ -214,7 +214,7 @@ namespace rubinius {
if(!entry->prediction()->nil_p()) {
entry->prediction()->invalidate();
}
entry->prediction(state, nil<MethodPrediction>());
entry->prediction(state, nil<Prediction>());
return name;
}

Expand Down Expand Up @@ -360,7 +360,7 @@ namespace rubinius {
entry->scope(state, scope);
entry->serial(state, serial);
entry->visibility(state, vis);
entry->prediction(state, nil<MethodPrediction>());
entry->prediction(state, nil<Prediction>());

return entry;
}
Expand Down
4 changes: 2 additions & 2 deletions machine/class/method_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace rubinius {
attr_accessor(method, Object);
attr_accessor(scope, Object);
attr_accessor(serial, Fixnum);
attr_accessor(prediction, MethodPrediction);
attr_accessor(prediction, Prediction);
attr_accessor(next, MethodTableBucket);

static void initialize(STATE, MethodTableBucket* obj) {
Expand All @@ -34,7 +34,7 @@ namespace rubinius {
obj->method(nil<Executable>());
obj->scope(nil<Object>());
obj->serial(nil<Fixnum>());
obj->prediction(nil<MethodPrediction>());
obj->prediction(nil<Prediction>());
obj->next(nil<MethodTableBucket>());
}

Expand Down
2 changes: 1 addition & 1 deletion machine/class/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ namespace rubinius {
if(entry) {
if(!entry->prediction()->nil_p()) {
entry->prediction()->invalidate();
entry->prediction(state, nil<MethodPrediction>());
entry->prediction(state, nil<Prediction>());
}
}

Expand Down
15 changes: 0 additions & 15 deletions machine/class/prediction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,4 @@ namespace rubinius {
Object* Prediction::valid_p(STATE) {
return RBOOL(valid() == valid_prediction);
}

void MethodPrediction::bootstrap(STATE) {
GO(method_prediction).set(state->memory()->new_class<Class, MethodPrediction>(
state, G(prediction), G(rubinius), "MethodPrediction"));
}

MethodPrediction* MethodPrediction::create(STATE, Module* module, Executable* executable) {
MethodPrediction* pred =
state->memory()->new_object<MethodPrediction>(state, G(method_prediction));

pred->module(state, module);
pred->executable(state, executable);

return pred;
}
}
26 changes: 0 additions & 26 deletions machine/class/prediction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,32 +53,6 @@ namespace rubinius {
virtual void populate_slot_locations() { }
};
};

class MethodPrediction : public Prediction {
public:
const static object_type type = MethodPredictionType;

attr_accessor(module, Module);
attr_accessor(executable, Executable);

static void bootstrap(STATE);
static void initialize(STATE, MethodPrediction* obj) {
Prediction::initialize(state, obj);

obj->module(nil<Module>());
obj->executable(nil<Executable>());
}

static MethodPrediction* create(STATE, Module* module, Executable* executable);

class Info : public Prediction::Info {
public:
BASIC_TYPEINFO(Prediction::Info)
virtual void mark(Object* obj, memory::ObjectMark& mark) {
auto_mark(obj, mark);
}
};
};
}

#endif
6 changes: 2 additions & 4 deletions machine/dispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ namespace rubinius {

if(msg->method) {
if(entry->prediction()->nil_p()) {
entry->prediction(state,
MethodPrediction::create(state, msg->module, msg->method));
entry->prediction(state, Prediction::create(state));
}
msg->prediction = entry->prediction();
return true;
Expand Down Expand Up @@ -158,8 +157,7 @@ namespace rubinius {

if(msg->method) {
if(entry->prediction()->nil_p()) {
entry->prediction(state,
MethodPrediction::create(state, msg->module, msg->method));
entry->prediction(state, Prediction::create(state));
}
msg->prediction = entry->prediction();
return true;
Expand Down
4 changes: 2 additions & 2 deletions machine/dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace rubinius {
class Executable;
class Module;
class Object;
class MethodPrediction;
class Prediction;
class Symbol;
struct LookupData;

Expand All @@ -19,7 +19,7 @@ namespace rubinius {
Module* module;
Executable* method;
Symbol* visibility;
MethodPrediction* prediction;
Prediction* prediction;
MethodMissingReason method_missing;

Dispatch(Symbol* name)
Expand Down
1 change: 0 additions & 1 deletion machine/ontology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ namespace rubinius {
NativeMethod::bootstrap(state);

Prediction::bootstrap(state);
MethodPrediction::bootstrap(state);
CallSite::bootstrap(state);
ConstantCache::bootstrap(state);
Fiber::bootstrap(state);
Expand Down
Loading

0 comments on commit 985ac9e

Please sign in to comment.