positioning wip

This commit is contained in:
Torsten Ruger
2018-06-02 16:12:01 +03:00
parent d1cc482f8f
commit aa6707337a
8 changed files with 84 additions and 91 deletions

View File

@ -12,14 +12,13 @@ module Risc
attr_reader :code , :method
def initialize(code, pos , method)
def initialize(code , method)
super(code,pos)
@code = code
@method = method
raise "Method nil" unless method
end
def init(at , method)
raise "No no" unless method.name == @method.name
def set(at )
next_pos = at + code.padded_length
if code.next
Position.set(code.next , next_pos, method)
@ -32,11 +31,7 @@ module Risc
Position.set( next_meth.cpu_instructions, next_cpu_pos , next_meth.binary)
end
end
def reset_to(pos , ignored)
super(pos, ignored)
init(pos , ignored)
Position.log.debug "ResetCode (#{pos.to_s(16)}) #{code}"
end
# insert a jump to the next instruction, at the last instruction
# thus hopping over the object header
def set_jump(at)

View File

@ -16,9 +16,9 @@ module Risc
#
class InstructionPosition < ObjectPosition
attr_reader :instruction , :binary
def initialize(instruction, pos , binary)
raise "not set #{binary}" if pos != 0 and !binary.is_a?(Parfait::BinaryCode)
super(instruction,pos)
def initialize(instruction , binary)
pos = 0
super(instruction)
@instruction = instruction
@binary = binary
end
@ -47,6 +47,25 @@ module Risc
init(pos , binary)
Position.log.debug "ResetInstruction (#{pos.to_s(16)}) #{instruction}"
end
# initialize the dependency graph for instructions
#
# starting from the given instruction, create InstructionPositions
# for it and the whole chain
#
# Set the next created to be dependent on the previous
def self.init( instruction , code)
while(instruction)
position = InstructionPosition.new(instruction , code)
nekst = instruction.next
if nekst
listener = InstructionListener.new( nekst )
position.register_event(:position_changed , listener)
end
instruction = nekst
end
position
end
end
end
end

View File

@ -7,11 +7,13 @@ module Risc
attr_reader :at , :object
def initialize( object, at)
@at = at
# initialize with a given object, first parameter
# The object ill be the key in global position map
# Give an integer as the actual position, where -1
# which means no legal position known
def initialize(object , pos )
@at = 0
@object = object
@listeners = []
raise "not int #{self}-#{at}" unless @at.is_a?(Integer)
end
def +(offset)
@ -31,13 +33,17 @@ module Risc
end
def reset_to(pos , guaranteed_nil )
return false if pos == at
trigger(:position_changed , self)
if((at - pos).abs > 1000)
raise "position set too far off #{pos}!=#{at} for #{object}:#{object.class}"
end
@at = pos
trigger(:position_changed , self)
true
end
def self.init(object , at = -1)
position = ObjectPosition.new(object , at)
Position.set_to( position , at)
end
end
end
end

View File

@ -56,52 +56,19 @@ module Risc
old.reset_to( old.at )
end
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
# in measures
#
# reseting to the same position as before, triggers code that propagates
def self.reset(position , to , extra)
log.debug "ReSetting #{position}, to:#{to.to_s(16)}, for #{position.object.class}-#{position.object}"
position.reset_to(to, extra)
if testing = @reverse_cache[ to ]
if testing.class != position.class
raise "Mismatch (at #{to.to_s(16)}) new:#{position}:#{position.class} , was #{testing}:#{testing.class}"
end
end
unless position.object.is_a? Label
@reverse_cache.delete(to)
@reverse_cache[position.at] = position
end
log.debug "Reset #{position} (#{to.to_s(16)}) for #{position.class}"
return position
end
def self.set( object , pos , extra = nil)
old = Position.positions[object]
return self.reset(old , pos , extra) if old
log.debug "Setting #{pos.to_s(16)} for #{object.class}-#{object}"
testing = self.at( pos )
position = for_at( object , pos , extra)
def self.set_to( position , to)
postest = Position.positions[position.object]
raise "Mismatch #{position}" if postest and postest != position
@reverse_cache.delete(position.at) unless position.object.is_a? Label
testing = self.at( position.at ) if position.at >= 0
if testing and testing.class != position.class
raise "Mismatch (at #{pos.to_s(16)}) was:#{position} #{position.class} #{position.object} , should #{testing}#{testing.class}"
end
self.positions[object] = position
position.init(pos , extra)
@reverse_cache[position.at] = position unless object.is_a? Label
log.debug "Set #{position} (#{pos.to_s(16)}) for #{position.class}"
self.positions[position.object] = position
@reverse_cache[to] = position unless position.object.is_a? Label
log.debug "Set #{position} (#{to.to_s(16)}) for #{position.class}"
position
end
def self.for_at(object , at , extra)
case object
when Parfait::BinaryCode
CodePosition.new(object,at , extra)
when Arm::Instruction , Risc::Instruction
InstructionPosition.new(object,at , extra)
else
ObjectPosition.new(object,at)
end
end
end
end
require_relative "object_position"