Permalink
Browse files

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.
  • Loading branch information...
1 parent 48ad90f commit cf3ffd70d43cf426c1464741c3c02f73d6aa0482 @dbussink dbussink committed Apr 30, 2013
@@ -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.
#
@@ -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
+
@@ -12,6 +12,7 @@ class.rbc
compactlookuptable.rbc
compiled_code.rbc
configuration.rbc
+constant_cache.rbc
constant_scope.rbc
dir.rbc
exception.rbc
@@ -14,6 +14,7 @@ class.rbc
compactlookuptable.rbc
compiled_code.rbc
configuration.rbc
+constant_cache.rbc
constant_scope.rbc
dir.rbc
encoding.rbc
@@ -14,6 +14,7 @@ class.rbc
compactlookuptable.rbc
compiled_code.rbc
configuration.rbc
+constant_cache.rbc
constant_scope.rbc
dir.rbc
encoding.rbc
@@ -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
@@ -0,0 +1,8 @@
+class ConstantCacheSpec
+
+ ConstantCacheTest = def constant_cache_test
+ Rubinius::VariableScope
+ end
+
+end
+
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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<Tuple>(Primitives::failure());
+ }
+ MachineCode* mcode = self->machine_code_;
+ return mcode->constant_caches(state);
+ }
+
+
int CompiledCode::start_line(STATE) {
return start_line();
}
@@ -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);
@@ -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_);
+ }
}
@@ -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);

0 comments on commit cf3ffd7

Please sign in to comment.