rename code.length tp mem_length with lots of noise impact
This commit is contained in:
parent
cffa7f1953
commit
8b8a8eea56
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user