diff --git a/lib/mom/instruction/dynamic_call.rb b/lib/mom/instruction/dynamic_call.rb index 52e1a5d1..ed036cc6 100644 --- a/lib/mom/instruction/dynamic_call.rb +++ b/lib/mom/instruction/dynamic_call.rb @@ -12,12 +12,10 @@ module Mom # See vool send statement # class DynamicCall < Instruction - attr :cached_type - attr :cached_method + attr :cache_entry def initialize(type = nil, method = nil) - @cached_type = type - @cached_method = method + @cache_entry = Parfait::CacheEntry.new(type, method) end def to_risc(context) diff --git a/lib/parfait.rb b/lib/parfait.rb index 894b75ba..16ce1375 100644 --- a/lib/parfait.rb +++ b/lib/parfait.rb @@ -13,6 +13,7 @@ require_relative "parfait/typed_method" require_relative "parfait/vool_method" require_relative "parfait/dictionary" require_relative "parfait/type" +require_relative "parfait/cache_entry" require_relative "parfait/message" require_relative "parfait/named_list" require_relative "parfait/space" diff --git a/lib/parfait/cache_entry.rb b/lib/parfait/cache_entry.rb new file mode 100644 index 00000000..5ba88d5b --- /dev/null +++ b/lib/parfait/cache_entry.rb @@ -0,0 +1,17 @@ +# For dynamic calls (ie method calls where the method can not be determined at compile time) +# we resolve the method at runtime, and then cache it. Aaron has shown that over 99% +# of call sites are type stable, so one cache entry at the moment +# +# A cache entry stores the type of the object and the TypedMethod that is to be called +# This is used in DynamicCall, see there +# +module Parfait + class CacheEntry < Object + attr :cached_type + attr :cached_method + def initialize(type , method) + @cached_type = type + @cached_method = method + end + end +end diff --git a/lib/risc/boot.rb b/lib/risc/boot.rb index 148f0f4e..138efd0a 100644 --- a/lib/risc/boot.rb +++ b/lib/risc/boot.rb @@ -139,6 +139,7 @@ module Risc :Class => {:instance_methods => :List, :instance_type => :Type, :name => :Word, :super_class_name => :Word , :instance_names => :List }, :Dictionary => {:keys => :List , :values => :List } , + :CacheEntry => {:cached_type => :Type , :cached_method => :TypedMethod } , :TypedMethod => {:name => :Word, :source => :Object, :instructions => :Object, :binary => :Object, :arguments => :Type , :for_type => :Type, :frame => :Type } , }