From 8b8a8eea56c974dec5a6f23693aa437cc0e9b44f Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 16 Sep 2014 17:16:56 +0300 Subject: [PATCH] rename code.length tp mem_length with lots of noise impact --- lib/elf/text_section.rb | 2 +- lib/register/assembler.rb | 35 ++++++--------- lib/register/code.rb | 4 +- lib/register/instruction.rb | 3 +- lib/register/reference.rb | 2 +- lib/stream_reader.rb | 4 +- lib/virtual/block.rb | 11 ++--- lib/virtual/boot_class.rb | 3 ++ lib/virtual/boot_space.rb | 5 ++- lib/virtual/compiled_method.rb | 6 ++- lib/virtual/constants.rb | 11 ++++- lib/virtual/object.rb | 78 +++++++++++++++++++++++++++++++--- lib/virtual/plock.rb | 8 ++-- lib/virtual/slot.rb | 2 +- 14 files changed, 124 insertions(+), 50 deletions(-) diff --git a/lib/elf/text_section.rb b/lib/elf/text_section.rb index ca3a03cc..a4d08bce 100644 --- a/lib/elf/text_section.rb +++ b/lib/elf/text_section.rb @@ -14,7 +14,7 @@ module Elf Elf::Constants::SHF_WRITE | Elf::Constants::SHF_ALLOC | Elf::Constants::SHF_EXECINSTR end - def length + def mem_length @text.length end def to_s diff --git a/lib/register/assembler.rb b/lib/register/assembler.rb index dcc8f534..6cf03ae2 100644 --- a/lib/register/assembler.rb +++ b/lib/register/assembler.rb @@ -23,14 +23,13 @@ module Register at = 4 @objects.each do |id , objekt| next unless objekt.is_a? Virtual::CompiledMethod - objekt.position = at - objekt.set_position at - at += objekt.length + objekt.set_position(at) + at += objekt.mem_length end @objects.each do |id , objekt| next if objekt.is_a? Virtual::CompiledMethod - objekt.position = at - at += objekt.length + objekt.set_position at + at += objekt.mem_length end end @@ -40,8 +39,8 @@ module Register mid , main = @objects.find{|k,objekt| objekt.is_a?(Virtual::CompiledMethod) and (objekt.name == :__init__ )} puts "function found #{main.name}" initial_jump = RegisterMachine.instance.b( main ) - initial_jump.position = 0 - initial_jump.assemble( @stream , self ) + initial_jump.set_position( 0) + initial_jump.assemble( @stream ) @objects.each do |id , objekt| next unless objekt.is_a? Virtual::CompiledMethod assemble_object( objekt ) @@ -55,7 +54,7 @@ module Register end def collect_object(object) - return object.length if @objects[object.object_id] + return object.mem_length if @objects[object.object_id] @objects[object.object_id] = object collect_object(object.layout[:names]) clazz = object.class.name.split("::").last @@ -63,7 +62,7 @@ module Register end def assemble_object obj - puts "Assemble #{obj.class}(#{obj.object_id}) at stream #{(@stream.length).to_s(16)} pos:#{obj.position.to_s(16)} , len:#{obj.length}" + puts "Assemble #{obj.class}(#{obj.object_id}) at stream #{(@stream.length).to_s(16)} pos:#{obj.position.to_s(16)} , len:#{obj.mem_length}" raise "Assemble #{obj.class} at #{@stream.length.to_s(16)} not #{obj.position.to_s(16)}" if @stream.length != obj.position clazz = obj.class.name.split("::").last send("assemble_#{clazz}".to_sym , obj) @@ -128,7 +127,6 @@ module Register def collect_BootSpace(space) collect_object(space.classes) collect_object(space.objects) - padded_words( 2 ) end def assemble_BootSpace(space) @@ -139,7 +137,6 @@ module Register collect_object(clazz.name ) collect_object(clazz.super_class_name) collect_object(clazz.instance_methods) - padded_words(3) end def assemble_BootClass(clazz) @@ -147,9 +144,6 @@ module Register end def collect_CompiledMethod(method) - # NOT an ARRAY, just a bag of bytes - length = method.blocks.inject(0) { |c , block| c += block.length } - padded(length) end @@ -164,36 +158,33 @@ module Register # TODO the assembly may have to move to the object to be more extensible method.blocks.each do |block| block.codes.each do |code| - code.assemble( @stream , self ) + code.assemble( @stream ) end end pad_after( count ) end def collect_String( str) - return padded( str.length + 1 ) end def collect_Symbol(sym) - return collect_String(sym.to_s) end def collect_StringConstant(sc) - return collect_String(sc.string) end def assemble_String( str ) str = str.string if str.is_a? Virtual::StringConstant str = str.to_s if str.is_a? Symbol - word = (str.length + 7) / 32 # all object are multiple of 8 words (7 for header) + word = (str.mem_length + 7) / 32 # all object are multiple of 8 words (7 for header) raise "String too long (implement split string!) #{word}" if word > 15 # first line is integers, convention is that following lines are the same TYPE_LENGTH.times { word = ((word << TYPE_BITS) + TYPE_INT) } @stream.write_uint32( word ) write_ref_for( str.layout[:names] , slot) #ref @stream.write str - pad_after(str.length) - #puts "String (#{slot.length}) stream #{@stream.length.to_s(16)}" + pad_after(str.mem_length) + #puts "String (#{slot.mem_length}) stream #{@stream.mem_length.to_s(16)}" end def assemble_Symbol(sym) @@ -237,7 +228,7 @@ module Register pad.times do @stream.write_uint8(0) end - #puts "padded #{length} with #{pad} stream pos #{@stream.length.to_s(16)}" + #puts "padded #{length} with #{pad} stream pos #{@stream.mem_length.to_s(16)}" end end diff --git a/lib/register/code.rb b/lib/register/code.rb index 93ee1be2..bba3196c 100644 --- a/lib/register/code.rb +++ b/lib/register/code.rb @@ -9,7 +9,7 @@ module Register # All code is position independant once assembled. # But for jumps and calls two passes are neccessary. # The first setting the position, the second assembling - class Code + class Bode def class_for clazz RegisterMachine.instance.class_for(clazz) @@ -35,7 +35,7 @@ module Register end # length for this code in bytes - def length + def mem_length raise "Not implemented #{inspect}" end diff --git a/lib/register/instruction.rb b/lib/register/instruction.rb index 37e70c94..fe3912db 100644 --- a/lib/register/instruction.rb +++ b/lib/register/instruction.rb @@ -12,12 +12,11 @@ module Register # Instruction derives from Code, for the assembly api - class Instruction < Code + class Instruction < Virtual::Object def initialize options @attributes = options end attr_reader :attributes - attr_accessor :position def opcode @attributes[:opcode] end diff --git a/lib/register/reference.rb b/lib/register/reference.rb index 997ab08b..23852ee8 100644 --- a/lib/register/reference.rb +++ b/lib/register/reference.rb @@ -12,7 +12,7 @@ module Register block.mov( self , right ) #move the value elsif right.is_a? StringConstant block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative - block.mov( Integer.new(self.register.next_reg_use) , right.length ) #and the length HACK TODO + block.mov( Integer.new(self.register.next_reg_use) , right.mem_length ) #and the length HACK TODO elsif right.is_a?(Boot::BootClass) or right.is_a?(Boot::MetaClass) block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative else diff --git a/lib/stream_reader.rb b/lib/stream_reader.rb index 081ff159..45598c87 100644 --- a/lib/stream_reader.rb +++ b/lib/stream_reader.rb @@ -8,7 +8,7 @@ module StreamReader def read_binary(size, count, type) d = __sr_read(size*count) ret = d.unpack(type*count) - return ret if ret.length > 1 + return ret if ret.mem_length > 1 return ret[0] end def read_uint32(n=1) @@ -80,7 +80,7 @@ module StreamWriter return __sr_write(str + 0.chr) end def write_cstr_prefixed(str) - write_uint8(str.length) + write_uint8(str.mem_length) return __sr_write(str) end def write_str(str) diff --git a/lib/virtual/block.rb b/lib/virtual/block.rb index 453664ad..2b8ff27f 100644 --- a/lib/virtual/block.rb +++ b/lib/virtual/block.rb @@ -19,7 +19,7 @@ module Virtual @codes = [] end - attr_reader :name , :codes , :method , :position + attr_reader :name , :codes , :method attr_accessor :branch def reachable ret = [] @@ -58,13 +58,14 @@ module Virtual def set_position at @position = at @codes.each do |code| - code.position = at - at += code.length + code.set_position( at) + raise code.inspect unless code.mem_length + at += code.mem_length end end - def length - @codes.inject(0){|count , instruction| count += instruction.length } + def mem_length + @codes.inject(0){|count , instruction| count += instruction.mem_length } end private diff --git a/lib/virtual/boot_class.rb b/lib/virtual/boot_class.rb index 62251214..71390dcd 100644 --- a/lib/virtual/boot_class.rb +++ b/lib/virtual/boot_class.rb @@ -43,6 +43,9 @@ module Virtual def layout @@CLAZZ end + def mem_length + padded_words(3) + end def to_s inspect end diff --git a/lib/virtual/boot_space.rb b/lib/virtual/boot_space.rb index c1ca70ab..625de98f 100644 --- a/lib/virtual/boot_space.rb +++ b/lib/virtual/boot_space.rb @@ -12,7 +12,7 @@ module Virtual # While data ususally would live in a .data section, we may also "inline" it into the code # in an oo system all data is represented as objects - class BootSpace + class BootSpace < Virtual::Object # Initialize with a string for cpu. Naming conventions are: for Machine XXX there exists a module XXX # with a XXXMachine in it that derives from Virtual::RegisterMachine @@ -114,5 +114,8 @@ module Virtual end c end + def mem_length + padded_words( 2 ) + end end end diff --git a/lib/virtual/compiled_method.rb b/lib/virtual/compiled_method.rb index 5e98a2e7..1a89b532 100644 --- a/lib/virtual/compiled_method.rb +++ b/lib/virtual/compiled_method.rb @@ -166,12 +166,16 @@ module Virtual add_code ::Register::RegisterMachine.instance.send(meth , *args) end + def mem_length + l = @blocks.inject(0) { |c , block| c += block.mem_length } + padded(l) + end # position of the function is the position of the entry block, is where we call def set_position at at += 8 #for the 2 header words @blocks.each do |block| block.set_position at - at = at + block.length + at = at + block.mem_length end end def position diff --git a/lib/virtual/constants.rb b/lib/virtual/constants.rb index 2d832cfa..f9264cf3 100644 --- a/lib/virtual/constants.rb +++ b/lib/virtual/constants.rb @@ -1,6 +1,6 @@ module Virtual - class Constant < ::Virtual::Value + class Constant < ::Virtual::Object end class TrueConstant < Constant end @@ -15,7 +15,7 @@ module Virtual def type Virtual::Reference end - def claszz + def clazz raise "abstract #{self}" end end @@ -40,12 +40,19 @@ module Virtual @string = str end attr_reader :string + def result= value class_for(MoveInstruction).new(value , self , :opcode => :mov) end def clazz BootSpace.space.get_or_create_class(:String) end + def layout + Virtual::Object.layout + end + def mem_length + padded(1 + string.length) + end end end \ No newline at end of file diff --git a/lib/virtual/object.rb b/lib/virtual/object.rb index e6f14349..406b3b5c 100644 --- a/lib/virtual/object.rb +++ b/lib/virtual/object.rb @@ -17,19 +17,24 @@ module Virtual # String String class Object def initialize - @position = -1 + @position = nil @length = -1 end - attr_accessor :position , :length , :layout + attr_accessor :length , :layout def position - raise "position accessed but not set at #{length} for #{self.objekt}" if @position == -1 + raise "position accessed but not set at #{length} for #{self.objekt}" if @position == nil @position end - + def set_position pos + raise "position set again #{pos}!=#{@position} for #{self}" if @position != nil and (@position != pos) + @position = pos + end def inspect Sof::Writer.write(self) end - + def mem_length + raise "abstract #{self}" + end @@EMPTY = { :names => [] , :types => []} def layout raise "Find me #{self}" @@ -58,7 +63,27 @@ module Virtual raise "linker encounters unknown class #{object.class}" end end - + # objects only come in lengths of multiple of 8 words + # but there is a constant overhead of 2 words, one for type, one for layout + # and as we would have to subtract 1 to make it work without overhead, we now have to add 7 + def padded len + a = 32 * (1 + (len + 7)/32 ) + #puts "#{a} for #{len}" + a + end + + def padded_words words + padded(words*4) # 4 == word length, a constant waiting for a home + end + + # pad_after is always in bytes and pads (writes 0's) up to the next 8 word boundary + def pad_after length + pad = padded(length) - length - 8 # for header, type and layout + pad.times do + @stream.write_uint8(0) + end + #puts "padded #{length} with #{pad} stream pos #{@stream.length.to_s(16)}" + end end end Parfait::Hash.class_eval do @@ -66,14 +91,55 @@ Parfait::Hash.class_eval do def layout @@HASH end + def set_position pos + @position = pos + end + def position + @position + end + def mem_length + Virtual::Object.new.padded_words(2) + end end Array.class_eval do def layout Virtual::Object.layout end + def set_position pos + @position = pos + end + def position + @position + end + def mem_length + Virtual::Object.new.padded_words(length()) + end end Symbol.class_eval do + def set_position pos + @position = pos + end + def position + @position + end def layout Virtual::Object.layout end + def mem_length + Virtual::Object.new.padded(1 + to_s.length()) + end +end +String.class_eval do + def set_position pos + @position = pos + end + def position + @position + end + def layout + Virtual::Object.layout + end + def mem_length + Virtual::Object.new.padded(1 + length()) + end end diff --git a/lib/virtual/plock.rb b/lib/virtual/plock.rb index 103b15df..59cc6395 100644 --- a/lib/virtual/plock.rb +++ b/lib/virtual/plock.rb @@ -37,9 +37,9 @@ module Virtual # Code interface follows. Note position is inheitted as is from Code # length of the Plock is the length of the block, plus the branch, plus data. - def length - len = @data.inject(super) {| sum , item | sum + item.length} - len + @branch_code.length + def mem_length + len = @data.inject(super) {| sum , item | sum + item.mem_length} + len + @branch_code.mem_length end # again, super + branch plus data @@ -48,7 +48,7 @@ module Virtual @branch_code.link_at pos , context @data.each do |code| code.link_at(pos , context) - pos += code.length + pos += code.mem_length end end diff --git a/lib/virtual/slot.rb b/lib/virtual/slot.rb index f22393be..6b162b11 100644 --- a/lib/virtual/slot.rb +++ b/lib/virtual/slot.rb @@ -8,7 +8,7 @@ module Virtual # additionally frame, self and return are slots in Message and NewMessage - class Slot < Value + class Slot RETURN = 0 SELF = 1 FRAME = 2