From aaa206fbcaea7ad1004593568eff189634f67747 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 31 May 2015 11:07:49 +0300 Subject: [PATCH] debugging missing layout --- lib/parfait/list.rb | 4 ++++ lib/parfait/module.rb | 4 ++++ lib/parfait/object.rb | 13 ++++++++----- lib/parfait/space.rb | 19 +++++++++++++++++++ lib/register/builtin/kernel.rb | 1 + lib/virtual.rb | 1 + lib/virtual/boot.rb | 9 +++++++-- lib/virtual/machine.rb | 3 ++- lib/virtual/parfait_adapter.rb | 14 ++++++++++---- lib/virtual/passes/collector.rb | 33 +++++++++++++++++++++++++++++++++ lib/virtual/passes/minimizer.rb | 5 +++-- 11 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 lib/virtual/passes/collector.rb diff --git a/lib/parfait/list.rb b/lib/parfait/list.rb index ac1da1df..06aacae1 100644 --- a/lib/parfait/list.rb +++ b/lib/parfait/list.rb @@ -15,6 +15,10 @@ module Parfait class List < Object + def initialize( ) + super() + end + def get_length internal_object_length - 1 end diff --git a/lib/parfait/module.rb b/lib/parfait/module.rb index f5104b4c..7995db4d 100644 --- a/lib/parfait/module.rb +++ b/lib/parfait/module.rb @@ -43,6 +43,10 @@ module Parfait method end + def remove_instance_method method + @instance_methods.delete method + end + def create_instance_method name , arg_names clazz = Space.object_space.get_class_by_name(self.name) raise "??? #{self.name}" unless clazz diff --git a/lib/parfait/object.rb b/lib/parfait/object.rb index 2501b22d..4837b557 100644 --- a/lib/parfait/object.rb +++ b/lib/parfait/object.rb @@ -43,17 +43,20 @@ module Parfait # private def set_layout(layout) - if( internal_object_get(LAYOUT_INDEX) ) + #if( was = internal_object_get(LAYOUT_INDEX) ) #TODO find out wat these objects are - # puts "Layout was set for #{self.class}" - return - end + #puts "Layout was set for #{self.class}" + #puts "#{self}" if self.class == Parfait::Word + # Space.object_space.check was + # return + #end + raise "Nil layout" unless layout internal_object_set(LAYOUT_INDEX , layout) end def get_layout() l = internal_object_get(LAYOUT_INDEX) - raise "No layout #{self.class}" unless l + raise "No layout #{self.class}:#{self.to_s} #{self.object_id}" unless l return l end diff --git a/lib/parfait/space.rb b/lib/parfait/space.rb index 30c3bf6b..4390a3e8 100644 --- a/lib/parfait/space.rb +++ b/lib/parfait/space.rb @@ -50,6 +50,25 @@ module Parfait @next_frame = @frames.first end + # double check that all objects dependents are really in the space too (debugging) + def double_check + @objects.each do |o| + check o + end + end + # private + def check object , recurse = true + raise "No good #{self.class}" unless @objects.include? object + puts "#{object.class}" + puts "#{object}" if object.class == Parfait::Word + check object.get_layout + return unless recurse + object.get_layout.each do |name| + check name , false + inst = object.instance_variable_get "@#{name}".to_sym + check inst , false + end + end @@object_space = nil # Make the object space globally available def self.object_space diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 4d4bc050..a5d3884f 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -6,6 +6,7 @@ module Builtin # so it is responsible for initial setup (and relocation) def __init__ context function = Virtual::CompiledMethodInfo.create_method("Kernel","__init__" , []) +# puts "INIT LAYOUT #{function.get_layout.get_layout}" function.info.return_type = Virtual::Integer main = Virtual::Machine.instance.space.get_main me = Virtual::Self.new(Virtual::Reference) diff --git a/lib/virtual.rb b/lib/virtual.rb index 98c0bac3..8dee2e1e 100644 --- a/lib/virtual.rb +++ b/lib/virtual.rb @@ -8,6 +8,7 @@ require "virtual/slots/slot" require "virtual/type" # the passes _are_ order dependant require "virtual/passes/minimizer" +require "virtual/passes/collector" require "virtual/passes/send_implementation" require "virtual/passes/get_implementation" require "virtual/passes/enter_implementation" diff --git a/lib/virtual/boot.rb b/lib/virtual/boot.rb index b83fd7b9..fd3eba94 100644 --- a/lib/virtual/boot.rb +++ b/lib/virtual/boot.rb @@ -44,6 +44,10 @@ module Virtual class_mappings.each do |name , clazz| # and the rest clazz.set_super_class(value_classes[3]) # superclasses are object end + supers = { "BinaryCode" => "Word", "Layout" => "List", "Class" => "Module"} + supers.each do |clazz , superclaszz| # set_super_class has no sideeffects, so setting twice ok + class_mappings[clazz].set_super_class class_mappings[superclaszz] + end # next create layouts by adding instance variable names to the layouts class_mappings.each do |name , clazz| variables = layouts[name] @@ -65,14 +69,15 @@ module Virtual [@space,@space.classes,@space.classes.keys, @space.classes.values,@space.objects].each do |o| @space.add_object o end - @space.late_init - + values.each {|v| v.init_layout } + # now update the layout on all objects created so far, # go through objects in space @space.objects.each do | o | o.init_layout end + @space.double_check boot_functions! end diff --git a/lib/virtual/machine.rb b/lib/virtual/machine.rb index 43615b32..b5e605c0 100644 --- a/lib/virtual/machine.rb +++ b/lib/virtual/machine.rb @@ -39,10 +39,11 @@ module Virtual @parser = Parser::Salama.new @passes = [ "Virtual::SendImplementation" ] end - attr_reader :message , :passes , :space , :class_mappings , :init + attr_reader :passes , :space , :class_mappings , :init def run_passes Minimizer.new.run + Collector.new.run @passes.each do |pass_class| blocks = [@init] @space.classes.values.each do |c| diff --git a/lib/virtual/parfait_adapter.rb b/lib/virtual/parfait_adapter.rb index 5799e274..3dda4b6d 100644 --- a/lib/virtual/parfait_adapter.rb +++ b/lib/virtual/parfait_adapter.rb @@ -6,21 +6,27 @@ module FakeMem def initialize + super() @memory = [0,nil] @position = nil @length = -1 if Parfait::Space.object_space and Parfait::Space.object_space.objects Parfait::Space.object_space.add_object self else - #Note: the else is handled in boot, by ading the space "by hand", as it slips though - #puts "Got away #{self.class}" + # Note: the else is handled in boot, by ading the space "by hand", as it slips though + # puts "Got away #{self.class}" + end + if Virtual::Machine.instance.class_mappings + init_layout + else + #puts "No init for #{self.class}:#{self.object_id}" end - init_layout if Virtual::Machine.instance.class_mappings end def init_layout vm_name = self.class.name.split("::").last clazz = Virtual::Machine.instance.class_mappings[vm_name] raise "Class not found #{vm_name}" unless clazz + raise "Layout not set #{vm_name}" unless clazz.object_layout self.set_layout clazz.object_layout end #TODO, this is copied from module Positioned, maybe avoid duplication ? @@ -163,7 +169,7 @@ module Virtual # Functions to generate parfait objects def self.new_word( string ) string = string.to_s if string.is_a? Symbol - word = Parfait::Word.new( string.length ) + word = Parfait::Word.new_object( string.length ) string.codepoints.each_with_index do |code , index | word.set_char(index + 1 , code) end diff --git a/lib/virtual/passes/collector.rb b/lib/virtual/passes/collector.rb new file mode 100644 index 00000000..42560b07 --- /dev/null +++ b/lib/virtual/passes/collector.rb @@ -0,0 +1,33 @@ +module Virtual + + # garbage collect anything that is in the space but not reachable from init + class Collector + def run + @keepers = [] + init= Parfait::Space.object_space.get_class_by_name("Kernel").get_instance_method "__init__" + keep init + end + + def keep object + return if @keepers.include? object + layout = object.get_layout + begin + puts "Object #{object.class} #{Parfait::Space.object_space.objects.include?(object)}" + puts "Object #{layout.object_id} #{Parfait::Space.object_space.objects.include?(layout)}" + keep layout + rescue => e + puts "for #{object.name}" + raise e + end + layout.each do |name| + inst = object.instance_variable_get "@#{name}".to_sym + keep inst + end + if object.is_a? Parfait::List + object.each do |item| + keep item + end + end + end + end +end diff --git a/lib/virtual/passes/minimizer.rb b/lib/virtual/passes/minimizer.rb index 31a190c6..303bd1fe 100644 --- a/lib/virtual/passes/minimizer.rb +++ b/lib/virtual/passes/minimizer.rb @@ -37,8 +37,9 @@ module Virtual end def dump_remaining - names = @gonners.collect {|f| f.name } - puts "Dump #{names}" + @gonners.each do |method| + method.for_class.remove_instance_method method + end end end end