rename code.length tp mem_length with lots of noise impact

This commit is contained in:
Torsten Ruger 2014-09-16 17:16:56 +03:00
parent cffa7f1953
commit 8b8a8eea56
14 changed files with 124 additions and 50 deletions

View File

@ -14,7 +14,7 @@ module Elf
Elf::Constants::SHF_WRITE | Elf::Constants::SHF_ALLOC | Elf::Constants::SHF_EXECINSTR Elf::Constants::SHF_WRITE | Elf::Constants::SHF_ALLOC | Elf::Constants::SHF_EXECINSTR
end end
def length def mem_length
@text.length @text.length
end end
def to_s def to_s

View File

@ -23,14 +23,13 @@ module Register
at = 4 at = 4
@objects.each do |id , objekt| @objects.each do |id , objekt|
next unless objekt.is_a? Virtual::CompiledMethod next unless objekt.is_a? Virtual::CompiledMethod
objekt.position = at objekt.set_position(at)
objekt.set_position at at += objekt.mem_length
at += objekt.length
end end
@objects.each do |id , objekt| @objects.each do |id , objekt|
next if objekt.is_a? Virtual::CompiledMethod next if objekt.is_a? Virtual::CompiledMethod
objekt.position = at objekt.set_position at
at += objekt.length at += objekt.mem_length
end end
end end
@ -40,8 +39,8 @@ module Register
mid , main = @objects.find{|k,objekt| objekt.is_a?(Virtual::CompiledMethod) and (objekt.name == :__init__ )} mid , main = @objects.find{|k,objekt| objekt.is_a?(Virtual::CompiledMethod) and (objekt.name == :__init__ )}
puts "function found #{main.name}" puts "function found #{main.name}"
initial_jump = RegisterMachine.instance.b( main ) initial_jump = RegisterMachine.instance.b( main )
initial_jump.position = 0 initial_jump.set_position( 0)
initial_jump.assemble( @stream , self ) initial_jump.assemble( @stream )
@objects.each do |id , objekt| @objects.each do |id , objekt|
next unless objekt.is_a? Virtual::CompiledMethod next unless objekt.is_a? Virtual::CompiledMethod
assemble_object( objekt ) assemble_object( objekt )
@ -55,7 +54,7 @@ module Register
end end
def collect_object(object) 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 @objects[object.object_id] = object
collect_object(object.layout[:names]) collect_object(object.layout[:names])
clazz = object.class.name.split("::").last clazz = object.class.name.split("::").last
@ -63,7 +62,7 @@ module Register
end end
def assemble_object obj 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 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 clazz = obj.class.name.split("::").last
send("assemble_#{clazz}".to_sym , obj) send("assemble_#{clazz}".to_sym , obj)
@ -128,7 +127,6 @@ module Register
def collect_BootSpace(space) def collect_BootSpace(space)
collect_object(space.classes) collect_object(space.classes)
collect_object(space.objects) collect_object(space.objects)
padded_words( 2 )
end end
def assemble_BootSpace(space) def assemble_BootSpace(space)
@ -139,7 +137,6 @@ module Register
collect_object(clazz.name ) collect_object(clazz.name )
collect_object(clazz.super_class_name) collect_object(clazz.super_class_name)
collect_object(clazz.instance_methods) collect_object(clazz.instance_methods)
padded_words(3)
end end
def assemble_BootClass(clazz) def assemble_BootClass(clazz)
@ -147,9 +144,6 @@ module Register
end end
def collect_CompiledMethod(method) 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 end
@ -164,36 +158,33 @@ module Register
# TODO the assembly may have to move to the object to be more extensible # TODO the assembly may have to move to the object to be more extensible
method.blocks.each do |block| method.blocks.each do |block|
block.codes.each do |code| block.codes.each do |code|
code.assemble( @stream , self ) code.assemble( @stream )
end end
end end
pad_after( count ) pad_after( count )
end end
def collect_String( str) def collect_String( str)
return padded( str.length + 1 )
end end
def collect_Symbol(sym) def collect_Symbol(sym)
return collect_String(sym.to_s)
end end
def collect_StringConstant(sc) def collect_StringConstant(sc)
return collect_String(sc.string)
end end
def assemble_String( str ) def assemble_String( str )
str = str.string if str.is_a? Virtual::StringConstant str = str.string if str.is_a? Virtual::StringConstant
str = str.to_s if str.is_a? Symbol 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 raise "String too long (implement split string!) #{word}" if word > 15
# first line is integers, convention is that following lines are the same # first line is integers, convention is that following lines are the same
TYPE_LENGTH.times { word = ((word << TYPE_BITS) + TYPE_INT) } TYPE_LENGTH.times { word = ((word << TYPE_BITS) + TYPE_INT) }
@stream.write_uint32( word ) @stream.write_uint32( word )
write_ref_for( str.layout[:names] , slot) #ref write_ref_for( str.layout[:names] , slot) #ref
@stream.write str @stream.write str
pad_after(str.length) pad_after(str.mem_length)
#puts "String (#{slot.length}) stream #{@stream.length.to_s(16)}" #puts "String (#{slot.mem_length}) stream #{@stream.mem_length.to_s(16)}"
end end
def assemble_Symbol(sym) def assemble_Symbol(sym)
@ -237,7 +228,7 @@ module Register
pad.times do pad.times do
@stream.write_uint8(0) @stream.write_uint8(0)
end 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
end end

View File

@ -9,7 +9,7 @@ module Register
# All code is position independant once assembled. # All code is position independant once assembled.
# But for jumps and calls two passes are neccessary. # But for jumps and calls two passes are neccessary.
# The first setting the position, the second assembling # The first setting the position, the second assembling
class Code class Bode
def class_for clazz def class_for clazz
RegisterMachine.instance.class_for(clazz) RegisterMachine.instance.class_for(clazz)
@ -35,7 +35,7 @@ module Register
end end
# length for this code in bytes # length for this code in bytes
def length def mem_length
raise "Not implemented #{inspect}" raise "Not implemented #{inspect}"
end end

View File

@ -12,12 +12,11 @@ module Register
# Instruction derives from Code, for the assembly api # Instruction derives from Code, for the assembly api
class Instruction < Code class Instruction < Virtual::Object
def initialize options def initialize options
@attributes = options @attributes = options
end end
attr_reader :attributes attr_reader :attributes
attr_accessor :position
def opcode def opcode
@attributes[:opcode] @attributes[:opcode]
end end

View File

@ -12,7 +12,7 @@ module Register
block.mov( self , right ) #move the value block.mov( self , right ) #move the value
elsif right.is_a? StringConstant elsif right.is_a? StringConstant
block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative 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) 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 block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative
else else

View File

@ -8,7 +8,7 @@ module StreamReader
def read_binary(size, count, type) def read_binary(size, count, type)
d = __sr_read(size*count) d = __sr_read(size*count)
ret = d.unpack(type*count) ret = d.unpack(type*count)
return ret if ret.length > 1 return ret if ret.mem_length > 1
return ret[0] return ret[0]
end end
def read_uint32(n=1) def read_uint32(n=1)
@ -80,7 +80,7 @@ module StreamWriter
return __sr_write(str + 0.chr) return __sr_write(str + 0.chr)
end end
def write_cstr_prefixed(str) def write_cstr_prefixed(str)
write_uint8(str.length) write_uint8(str.mem_length)
return __sr_write(str) return __sr_write(str)
end end
def write_str(str) def write_str(str)

View File

@ -19,7 +19,7 @@ module Virtual
@codes = [] @codes = []
end end
attr_reader :name , :codes , :method , :position attr_reader :name , :codes , :method
attr_accessor :branch attr_accessor :branch
def reachable ret = [] def reachable ret = []
@ -58,13 +58,14 @@ module Virtual
def set_position at def set_position at
@position = at @position = at
@codes.each do |code| @codes.each do |code|
code.position = at code.set_position( at)
at += code.length raise code.inspect unless code.mem_length
at += code.mem_length
end end
end end
def length def mem_length
@codes.inject(0){|count , instruction| count += instruction.length } @codes.inject(0){|count , instruction| count += instruction.mem_length }
end end
private private

View File

@ -43,6 +43,9 @@ module Virtual
def layout def layout
@@CLAZZ @@CLAZZ
end end
def mem_length
padded_words(3)
end
def to_s def to_s
inspect inspect
end end

View File

@ -12,7 +12,7 @@ module Virtual
# While data ususally would live in a .data section, we may also "inline" it into the code # 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 # 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 # 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 # with a XXXMachine in it that derives from Virtual::RegisterMachine
@ -114,5 +114,8 @@ module Virtual
end end
c c
end end
def mem_length
padded_words( 2 )
end
end end
end end

View File

@ -166,12 +166,16 @@ module Virtual
add_code ::Register::RegisterMachine.instance.send(meth , *args) add_code ::Register::RegisterMachine.instance.send(meth , *args)
end 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 # position of the function is the position of the entry block, is where we call
def set_position at def set_position at
at += 8 #for the 2 header words at += 8 #for the 2 header words
@blocks.each do |block| @blocks.each do |block|
block.set_position at block.set_position at
at = at + block.length at = at + block.mem_length
end end
end end
def position def position

View File

@ -1,6 +1,6 @@
module Virtual module Virtual
class Constant < ::Virtual::Value class Constant < ::Virtual::Object
end end
class TrueConstant < Constant class TrueConstant < Constant
end end
@ -15,7 +15,7 @@ module Virtual
def type def type
Virtual::Reference Virtual::Reference
end end
def claszz def clazz
raise "abstract #{self}" raise "abstract #{self}"
end end
end end
@ -40,12 +40,19 @@ module Virtual
@string = str @string = str
end end
attr_reader :string attr_reader :string
def result= value def result= value
class_for(MoveInstruction).new(value , self , :opcode => :mov) class_for(MoveInstruction).new(value , self , :opcode => :mov)
end end
def clazz def clazz
BootSpace.space.get_or_create_class(:String) BootSpace.space.get_or_create_class(:String)
end end
def layout
Virtual::Object.layout
end
def mem_length
padded(1 + string.length)
end
end end
end end

View File

@ -17,19 +17,24 @@ module Virtual
# String String # String String
class Object class Object
def initialize def initialize
@position = -1 @position = nil
@length = -1 @length = -1
end end
attr_accessor :position , :length , :layout attr_accessor :length , :layout
def position 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 @position
end end
def set_position pos
raise "position set again #{pos}!=#{@position} for #{self}" if @position != nil and (@position != pos)
@position = pos
end
def inspect def inspect
Sof::Writer.write(self) Sof::Writer.write(self)
end end
def mem_length
raise "abstract #{self}"
end
@@EMPTY = { :names => [] , :types => []} @@EMPTY = { :names => [] , :types => []}
def layout def layout
raise "Find me #{self}" raise "Find me #{self}"
@ -58,7 +63,27 @@ module Virtual
raise "linker encounters unknown class #{object.class}" raise "linker encounters unknown class #{object.class}"
end end
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
end end
Parfait::Hash.class_eval do Parfait::Hash.class_eval do
@ -66,14 +91,55 @@ Parfait::Hash.class_eval do
def layout def layout
@@HASH @@HASH
end end
def set_position pos
@position = pos
end
def position
@position
end
def mem_length
Virtual::Object.new.padded_words(2)
end
end end
Array.class_eval do Array.class_eval do
def layout def layout
Virtual::Object.layout Virtual::Object.layout
end end
def set_position pos
@position = pos
end
def position
@position
end
def mem_length
Virtual::Object.new.padded_words(length())
end
end end
Symbol.class_eval do Symbol.class_eval do
def set_position pos
@position = pos
end
def position
@position
end
def layout def layout
Virtual::Object.layout Virtual::Object.layout
end 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 end

View File

@ -37,9 +37,9 @@ module Virtual
# Code interface follows. Note position is inheitted as is from Code # 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. # length of the Plock is the length of the block, plus the branch, plus data.
def length def mem_length
len = @data.inject(super) {| sum , item | sum + item.length} len = @data.inject(super) {| sum , item | sum + item.mem_length}
len + @branch_code.length len + @branch_code.mem_length
end end
# again, super + branch plus data # again, super + branch plus data
@ -48,7 +48,7 @@ module Virtual
@branch_code.link_at pos , context @branch_code.link_at pos , context
@data.each do |code| @data.each do |code|
code.link_at(pos , context) code.link_at(pos , context)
pos += code.length pos += code.mem_length
end end
end end

View File

@ -8,7 +8,7 @@ module Virtual
# additionally frame, self and return are slots in Message and NewMessage # additionally frame, self and return are slots in Message and NewMessage
class Slot < Value class Slot
RETURN = 0 RETURN = 0
SELF = 1 SELF = 1
FRAME = 2 FRAME = 2