From cf3ffd70d43cf426c1464741c3c02f73d6aa0482 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 30 Apr 2013 17:19:51 +0200 Subject: [PATCH] Expose ConstantCache to Ruby land like CallSite This adds a bunch of basic specs for ConstantCache and exposes this object to Ruby land so people can peek at which constants are cached in different places. --- kernel/bootstrap/compiled_code.rb | 5 ++++ kernel/bootstrap/constant_cache.rb | 32 +++++++++++++++++++++ kernel/bootstrap/load_order18.txt | 1 + kernel/bootstrap/load_order19.txt | 1 + kernel/bootstrap/load_order20.txt | 1 + spec/core/constantcache/executable_spec.rb | 11 +++++++ spec/core/constantcache/fixtures/classes.rb | 8 ++++++ spec/core/constantcache/ip_spec.rb | 11 +++++++ spec/core/constantcache/location_spec.rb | 11 +++++++ spec/core/constantcache/name_spec.rb | 14 +++++++++ spec/core/constantcache/scope_spec.rb | 14 +++++++++ spec/core/constantcache/serial_spec.rb | 13 +++++++++ spec/core/constantcache/under_spec.rb | 17 +++++++++++ spec/core/constantcache/value_spec.rb | 14 +++++++++ vm/builtin/compiledcode.cpp | 13 +++++++++ vm/builtin/compiledcode.hpp | 3 ++ vm/builtin/constant_cache.cpp | 8 ++++++ vm/builtin/constant_cache.hpp | 6 ++++ 18 files changed, 183 insertions(+) create mode 100644 kernel/bootstrap/constant_cache.rb create mode 100644 spec/core/constantcache/executable_spec.rb create mode 100644 spec/core/constantcache/fixtures/classes.rb create mode 100644 spec/core/constantcache/ip_spec.rb create mode 100644 spec/core/constantcache/location_spec.rb create mode 100644 spec/core/constantcache/name_spec.rb create mode 100644 spec/core/constantcache/scope_spec.rb create mode 100644 spec/core/constantcache/serial_spec.rb create mode 100644 spec/core/constantcache/under_spec.rb create mode 100644 spec/core/constantcache/value_spec.rb diff --git a/kernel/bootstrap/compiled_code.rb b/kernel/bootstrap/compiled_code.rb index 43ad2b15ea..336ff55b47 100644 --- a/kernel/bootstrap/compiled_code.rb +++ b/kernel/bootstrap/compiled_code.rb @@ -20,6 +20,11 @@ def call_sites raise PrimitiveFailure, "CompiledCode#call_sites primitive failed" end + def constant_caches + Rubinius.primitive :compiledcode_constant_caches + raise PrimitiveFailure, "CompiledCode#constant_caches primitive failed" + end + # Return the CompiledCode for caller of the method that called # .of_sender. # diff --git a/kernel/bootstrap/constant_cache.rb b/kernel/bootstrap/constant_cache.rb new file mode 100644 index 0000000000..221e092549 --- /dev/null +++ b/kernel/bootstrap/constant_cache.rb @@ -0,0 +1,32 @@ +# -*- encoding: us-ascii -*- + +module Rubinius + class ConstantCache + + attr_reader :name + attr_reader :value + attr_reader :under + attr_reader :scope + attr_reader :executable + + def ip + Rubinius.primitive :constant_cache_ip + raise PrimitiveFailure, "CallSite#ip primitive failed" + end + + def serial + Rubinius.primitive :constant_cache_serial + raise PrimitiveFailure, "CallSite#serial primitive failed" + end + + def location + "#{@executable.file}:#{@executable.line_from_ip(ip)}" + end + + def inspect + "#<#{self.class.name}:0x#{self.object_id.to_s(16)} #{location}##{@name} constant=#{@value} under=#{@under}>" + end + + end +end + diff --git a/kernel/bootstrap/load_order18.txt b/kernel/bootstrap/load_order18.txt index c75fab0336..a48461ed47 100644 --- a/kernel/bootstrap/load_order18.txt +++ b/kernel/bootstrap/load_order18.txt @@ -12,6 +12,7 @@ class.rbc compactlookuptable.rbc compiled_code.rbc configuration.rbc +constant_cache.rbc constant_scope.rbc dir.rbc exception.rbc diff --git a/kernel/bootstrap/load_order19.txt b/kernel/bootstrap/load_order19.txt index bc3caefd20..f25df8f69b 100644 --- a/kernel/bootstrap/load_order19.txt +++ b/kernel/bootstrap/load_order19.txt @@ -14,6 +14,7 @@ class.rbc compactlookuptable.rbc compiled_code.rbc configuration.rbc +constant_cache.rbc constant_scope.rbc dir.rbc encoding.rbc diff --git a/kernel/bootstrap/load_order20.txt b/kernel/bootstrap/load_order20.txt index bc3caefd20..f25df8f69b 100644 --- a/kernel/bootstrap/load_order20.txt +++ b/kernel/bootstrap/load_order20.txt @@ -14,6 +14,7 @@ class.rbc compactlookuptable.rbc compiled_code.rbc configuration.rbc +constant_cache.rbc constant_scope.rbc dir.rbc encoding.rbc diff --git a/spec/core/constantcache/executable_spec.rb b/spec/core/constantcache/executable_spec.rb new file mode 100644 index 0000000000..b7867d49b9 --- /dev/null +++ b/spec/core/constantcache/executable_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#executable" do + before :each do + @constant_cache = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + end + + it "has the correct executable for the constant cache" do + @constant_cache.executable.should == ConstantCacheSpec::ConstantCacheTest + end +end diff --git a/spec/core/constantcache/fixtures/classes.rb b/spec/core/constantcache/fixtures/classes.rb new file mode 100644 index 0000000000..a39dc88bf3 --- /dev/null +++ b/spec/core/constantcache/fixtures/classes.rb @@ -0,0 +1,8 @@ +class ConstantCacheSpec + + ConstantCacheTest = def constant_cache_test + Rubinius::VariableScope + end + +end + diff --git a/spec/core/constantcache/ip_spec.rb b/spec/core/constantcache/ip_spec.rb new file mode 100644 index 0000000000..f4abc13062 --- /dev/null +++ b/spec/core/constantcache/ip_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#ip" do + before :each do + @constant_cache = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + end + + it "has the correct ip for the constant cache" do + @constant_cache.ip.should == 0 + end +end diff --git a/spec/core/constantcache/location_spec.rb b/spec/core/constantcache/location_spec.rb new file mode 100644 index 0000000000..13254e91d8 --- /dev/null +++ b/spec/core/constantcache/location_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#location" do + before :each do + @constant_cache = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + end + + it "has the correct location for the constant cache" do + @constant_cache.location.should =~ %r{spec/core/constantcache/fixtures/classes\.rb:4$} + end +end diff --git a/spec/core/constantcache/name_spec.rb b/spec/core/constantcache/name_spec.rb new file mode 100644 index 0000000000..e8e53b685f --- /dev/null +++ b/spec/core/constantcache/name_spec.rb @@ -0,0 +1,14 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#name" do + before :each do + @constant_cache_base = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + @constant_cache_under = ConstantCacheSpec::ConstantCacheTest.constant_caches[1] + + end + + it "has the correct name for the constant cache" do + @constant_cache_base.name.should == :Rubinius + @constant_cache_under.name.should == :VariableScope + end +end diff --git a/spec/core/constantcache/scope_spec.rb b/spec/core/constantcache/scope_spec.rb new file mode 100644 index 0000000000..19f938d7b0 --- /dev/null +++ b/spec/core/constantcache/scope_spec.rb @@ -0,0 +1,14 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#scope" do + before :each do + ConstantCacheSpec.new.constant_cache_test + @constant_cache_base = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + @constant_cache_under = ConstantCacheSpec::ConstantCacheTest.constant_caches[1] + end + + it "has a scope after the method is called" do + @constant_cache_base.scope.should be_an_instance_of(Rubinius::ConstantScope) + @constant_cache_under.scope.should be_an_instance_of(Rubinius::ConstantScope) + end +end diff --git a/spec/core/constantcache/serial_spec.rb b/spec/core/constantcache/serial_spec.rb new file mode 100644 index 0000000000..b68310522e --- /dev/null +++ b/spec/core/constantcache/serial_spec.rb @@ -0,0 +1,13 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#scope" do + before :each do + @constant_cache_base = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + @constant_cache_under = ConstantCacheSpec::ConstantCacheTest.constant_caches[1] + end + + it "returns an integer for the serial" do + @constant_cache_base.serial.should be_kind_of(Integer) + @constant_cache_under.serial.should be_kind_of(Integer) + end +end diff --git a/spec/core/constantcache/under_spec.rb b/spec/core/constantcache/under_spec.rb new file mode 100644 index 0000000000..95383db15c --- /dev/null +++ b/spec/core/constantcache/under_spec.rb @@ -0,0 +1,17 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#under" do + before :each do + ConstantCacheSpec.new.constant_cache_test + @constant_cache_base = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + @constant_cache_under = ConstantCacheSpec::ConstantCacheTest.constant_caches[1] + end + + it "has no under value for a top level constant" do + @constant_cache_base.under.should be_nil + end + + it "has the correct under value for a scoped constant" do + @constant_cache_under.under.should == Rubinius + end +end diff --git a/spec/core/constantcache/value_spec.rb b/spec/core/constantcache/value_spec.rb new file mode 100644 index 0000000000..61f499cb67 --- /dev/null +++ b/spec/core/constantcache/value_spec.rb @@ -0,0 +1,14 @@ +require File.expand_path('../fixtures/classes.rb', __FILE__) + +describe "Rubinius::ConstantCache#under" do + before :each do + ConstantCacheSpec.new.constant_cache_test + @constant_cache_base = ConstantCacheSpec::ConstantCacheTest.constant_caches[0] + @constant_cache_under = ConstantCacheSpec::ConstantCacheTest.constant_caches[1] + end + + it "returns the cached constant" do + @constant_cache_base.value.should == Rubinius + @constant_cache_under.value.should == Rubinius::VariableScope + end +end diff --git a/vm/builtin/compiledcode.cpp b/vm/builtin/compiledcode.cpp index 054171ffd6..3bc14bc127 100644 --- a/vm/builtin/compiledcode.cpp +++ b/vm/builtin/compiledcode.cpp @@ -83,6 +83,19 @@ namespace rubinius { return mcode->call_sites(state); } + Tuple* CompiledCode::constant_caches(STATE, CallFrame* calling_environment) { + GCTokenImpl gct; + CompiledCode* self = this; + OnStack<1> os(state, self); + + if(self->machine_code_ == NULL) { + if(!self->internalize(state, gct, calling_environment)) return force_as(Primitives::failure()); + } + MachineCode* mcode = self->machine_code_; + return mcode->constant_caches(state); + } + + int CompiledCode::start_line(STATE) { return start_line(); } diff --git a/vm/builtin/compiledcode.hpp b/vm/builtin/compiledcode.hpp index fff2af8257..3e8438370a 100644 --- a/vm/builtin/compiledcode.hpp +++ b/vm/builtin/compiledcode.hpp @@ -126,6 +126,9 @@ namespace rubinius { // Rubinius.primitive :compiledcode_call_sites Tuple* call_sites(STATE, CallFrame* calling_environment); + // Rubinius.primitive :compiledcode_constant_caches + Tuple* constant_caches(STATE, CallFrame* calling_environment); + String* full_name(STATE); bool kernel_method(STATE); diff --git a/vm/builtin/constant_cache.cpp b/vm/builtin/constant_cache.cpp index 15ad3670e4..9727445b75 100644 --- a/vm/builtin/constant_cache.cpp +++ b/vm/builtin/constant_cache.cpp @@ -45,5 +45,13 @@ namespace rubinius { cache->serial_ = -1; return cache; } + + Integer* ConstantCache::ip_prim(STATE) { + return Integer::from(state, ip_); + } + + Integer* ConstantCache::serial_prim(STATE) { + return Integer::from(state, serial_); + } } diff --git a/vm/builtin/constant_cache.hpp b/vm/builtin/constant_cache.hpp index cb7fcc6203..69c02e1497 100644 --- a/vm/builtin/constant_cache.hpp +++ b/vm/builtin/constant_cache.hpp @@ -37,6 +37,12 @@ namespace rubinius { int ip() { return ip_; } int serial() { return serial_; } + // Rubinius.primitive :constant_cache_ip + Integer* ip_prim(STATE); + + // Rubinius.primitive :constant_cache_serial + Integer* serial_prim(STATE); + static void init(STATE); static ConstantCache* create(STATE, ConstantCache* cache, Object* value, ConstantScope* scope); static ConstantCache* create(STATE, ConstantCache* cache, Object* value, Module* under, ConstantScope* scope);