FPDebug: refactor (use value-object for data address of members)

git-svn-id: trunk@44382 -
This commit is contained in:
martin 2014-03-08 22:07:32 +00:00
parent 8cec6d7044
commit 32f60ff178

View File

@ -599,10 +599,18 @@ type
FValueSymbol: TDbgDwarfValueIdentifier;
FTypeCastTargetType: TDbgDwarfTypeIdentifier;
FTypeCastSourceValue: TFpDbgValue;
FStructureValue: TFpDbgDwarfValue;
FLastMember: TFpDbgDwarfValue;
FLastError: TFpError;
function MemManager: TFpDbgMemManager; inline;
function AddressSize: Byte; inline;
procedure SetStructureValue(AValue: TFpDbgDwarfValue);
protected
procedure DoReferenceAdded; override;
procedure DoReferenceReleased; override;
procedure CircleBackRefActiveChanged(NewActive: Boolean); override;
procedure SetLastMember(ALastMember: TFpDbgDwarfValue);
function GetLastError: TFpError; override;
function DataAddr: TFpDbgMemLocation;
function OrdOrDataAddr: TFpDbgMemLocation;
@ -612,8 +620,6 @@ type
function GetFieldFlags: TFpDbgValueFieldFlags; override;
function HasTypeCastInfo: Boolean;
function IsValidTypeCast: Boolean; virtual;
procedure DoReferenceAdded; override;
procedure DoReferenceReleased; override;
function GetKind: TDbgSymbolKind; override;
function GetAddress: TFpDbgMemLocation; override;
function GetMemberCount: Integer; override;
@ -628,7 +634,8 @@ type
procedure SetValueSymbol(AValueSymbol: TDbgDwarfValueIdentifier);
function SetTypeCastInfo(AStructure: TDbgDwarfTypeIdentifier;
ASource: TFpDbgValue): Boolean; // Used for Typecast
// SourceValue: TFpDbgValue
// StructureValue: Any Value returned via GetMember points to its structure
property StructureValue: TFpDbgDwarfValue read FStructureValue write SetStructureValue;
end;
{ TFpDbgDwarfValueSized }
@ -825,7 +832,6 @@ type
TFpDbgDwarfValueArray = class(TFpDbgDwarfValue)
private
FResVal: TFpDbgValue;
FAddrObj: TFpDbgDwarfValueConstAddress;
protected
function GetFieldFlags: TFpDbgValueFieldFlags; override;
@ -906,15 +912,15 @@ type
TDbgDwarfValueIdentifier = class(TDbgDwarfIdentifier) // var, const, member, ...
private
// StructureValueInfo, Member and subproc may need containing class
FStructureValueInfo: TFpDbgSymbolBase;
procedure SetStructureValueInfo(AValue: TFpDbgSymbolBase);
FStructureValueInfo: TDbgDwarfIdentifier;
procedure SetStructureValueInfo(AValue: TDbgDwarfIdentifier);
protected
FValueObject: TFpDbgDwarfValue;
FMembers: TFpDbgCircularRefCntObjList;
procedure CircleBackRefActiveChanged(ANewActive: Boolean); override;
procedure SetParentTypeInfo(AValue: TDbgDwarfIdentifier); override;
function GetValueAddress(AValueObj: TFpDbgDwarfValue; out AnAddress: TFpDbgMemLocation): Boolean; virtual;
function GetValueAddress({%H-}AValueObj: TFpDbgDwarfValue;{%H-} out AnAddress: TFpDbgMemLocation): Boolean; virtual;
function GetValueDataAddress(AValueObj: TFpDbgDwarfValue; out AnAddress: TFpDbgMemLocation;
ATargetType: TDbgDwarfTypeIdentifier = nil): Boolean;
procedure KindNeeded; override;
@ -928,7 +934,7 @@ type
destructor Destroy; override;
class function CreateValueSubClass(AName: String; AnInformationEntry: TDwarfInformationEntry): TDbgDwarfValueIdentifier;
property StructureValueInfo: TFpDbgSymbolBase read FStructureValueInfo write SetStructureValueInfo;
property StructureValueInfo: TDbgDwarfIdentifier read FStructureValueInfo write SetStructureValueInfo;
end;
{ TDbgDwarfValueLocationIdentifier }
@ -1164,7 +1170,6 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
.ParentTypeInfo --> nil
ParentTypeInfo: has a weak RefCount (only AddRef, if self has other refs)
StructureValueInfo: weak Ref (Struct has a ref to member, via parent)
AnObject = TDbgDwarfIdentifierVariable
@ -1184,7 +1189,6 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
FField = TDbgDwarfIdentifierMember (declared in TBarBase)
|-- .TypeInfo --> Integer = TDbgDwarfBaseIdentifierBase [*1]
|-- .ParentTypeInfo --> TBarBase
|-- .StructureValueInfo --> AnObject
[*1] May have TDbgDwarfTypeIdentifierDeclaration or others
*)
@ -1935,8 +1939,8 @@ begin
// FAddrObj.RefCount: hold by self
i := 1;
// FAddrObj.RefCount: hold by FResVal (ignore only, if FResVAl is not hold by others)
if (FResVal <> nil) and (FResVal.RefCount = 1) then
// FAddrObj.RefCount: hold by FLastMember (ignore only, if FLastMember is not hold by others)
if (FLastMember <> nil) and (FLastMember.RefCount = 1) then
i := 2;
if (FAddrObj = nil) or (FAddrObj.RefCount > i) then begin
FAddrObj.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FAddrObj, 'TDbgDwarfArraySymbolValue'){$ENDIF};
@ -1947,15 +1951,15 @@ begin
FAddrObj.Update(Addr);
end;
if (FResVal = nil) or (FResVal.RefCount > 1) then begin
FResVal.ReleaseReference;
FResVal := FOwner.TypeInfo.TypeCastValue(FAddrObj);
if (FLastMember = nil) or (FLastMember.RefCount > 1) then begin
SetLastMember(TFpDbgDwarfValue(FOwner.TypeInfo.TypeCastValue(FAddrObj)));
FLastMember.ReleaseReference;
end
else begin
TFpDbgDwarfValue(FResVal).SetTypeCastInfo(TDbgDwarfTypeIdentifier(FOwner.TypeInfo), FAddrObj);
TFpDbgDwarfValue(FLastMember).SetTypeCastInfo(TDbgDwarfTypeIdentifier(FOwner.TypeInfo), FAddrObj);
end;
Result := FResVal;
Result := FLastMember;
end;
function TFpDbgDwarfValueArray.GetMemberCount: Integer;
@ -2037,7 +2041,6 @@ end;
destructor TFpDbgDwarfValueArray.Destroy;
begin
FAddrObj.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FAddrObj, 'TDbgDwarfArraySymbolValue'){$ENDIF};
FResVal.ReleaseReference;
inherited Destroy;
end;
@ -2681,10 +2684,9 @@ begin
FMembers := TFpDbgCircularRefCntObjList.Create;
FMembers.Add(tmp);
TDbgDwarfValueIdentifier(tmp).StructureValueInfo := Self;
Result := tmp.Value;
end;
SetLastMember(TFpDbgDwarfValue(Result));
end;
function TFpDbgDwarfValueStructTypeCast.GetMember(AIndex: Integer): TFpDbgValue;
@ -2702,10 +2704,9 @@ begin
FMembers := TFpDbgCircularRefCntObjList.Create;
FMembers.Add(tmp);
TDbgDwarfValueIdentifier(tmp).StructureValueInfo := Self;
Result := tmp.Value;
end;
SetLastMember(TFpDbgDwarfValue(Result));
end;
function TFpDbgDwarfValueStructTypeCast.GetMemberCount: Integer;
@ -2812,6 +2813,18 @@ begin
Result := FOwner.FCU.FAddressSize;
end;
procedure TFpDbgDwarfValue.SetStructureValue(AValue: TFpDbgDwarfValue);
begin
if FStructureValue = AValue then
exit;
if CircleBackRefsActive and (FStructureValue <> nil) then
FStructureValue.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FStructureValue, 'TDbgDwarfSymbolValue'){$ENDIF};
FStructureValue := AValue;
if CircleBackRefsActive and (FStructureValue <> nil) then
FStructureValue.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FStructureValue, 'TDbgDwarfSymbolValue'){$ENDIF};
end;
function TFpDbgDwarfValue.GetLastError: TFpError;
begin
Result := FLastError;
@ -2937,15 +2950,42 @@ end;
procedure TFpDbgDwarfValue.DoReferenceAdded;
begin
inherited DoReferenceAdded;
if (FValueSymbol <> nil) and (RefCount = 2) then
FValueSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValueSymbol, 'TDbgDwarfSymbolValue'){$ENDIF};
DoPlainReferenceAdded;
end;
procedure TFpDbgDwarfValue.DoReferenceReleased;
begin
inherited DoReferenceReleased;
if (FValueSymbol <> nil) and (RefCount = 1) then
NilThenReleaseRef(FValueSymbol {$IFDEF WITH_REFCOUNT_DEBUG}, @FValueSymbol, 'TDbgDwarfSymbolValue'{$ENDIF});
DoPlainReferenceReleased;
end;
procedure TFpDbgDwarfValue.CircleBackRefActiveChanged(NewActive: Boolean);
begin
inherited CircleBackRefActiveChanged(NewActive);
if NewActive then;
if CircleBackRefsActive then begin
if FValueSymbol <> nil then
FValueSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValueSymbol, 'TDbgDwarfSymbolValue'){$ENDIF};
if FStructureValue <> nil then
FStructureValue.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FStructureValue, 'TDbgDwarfSymbolValue'){$ENDIF};
end
else begin
if FValueSymbol <> nil then
FValueSymbol.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValueSymbol, 'TDbgDwarfSymbolValue'){$ENDIF};
if FStructureValue <> nil then
FStructureValue.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FStructureValue, 'TDbgDwarfSymbolValue'){$ENDIF};
end;
end;
procedure TFpDbgDwarfValue.SetLastMember(ALastMember: TFpDbgDwarfValue);
begin
if FLastMember <> nil then
FLastMember.ReleaseCirclularReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FLastMember, 'TDbgDwarfSymbolValue'){$ENDIF};
FLastMember := ALastMember;
if FLastMember <> nil then begin
FLastMember.SetStructureValue(Self);
FLastMember.AddCirclularReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FLastMember, 'TDbgDwarfSymbolValue'){$ENDIF};
end;
end;
function TFpDbgDwarfValue.GetKind: TDbgSymbolKind;
@ -2988,6 +3028,7 @@ begin
if m <> nil then
Result := m.Value;
end;
SetLastMember(TFpDbgDwarfValue(Result));
end;
function TFpDbgDwarfValue.GetMember(AIndex: Integer): TFpDbgValue;
@ -3000,6 +3041,7 @@ begin
if m <> nil then
Result := m.Value;
end;
SetLastMember(TFpDbgDwarfValue(Result));
end;
function TFpDbgDwarfValue.GetDbgSymbol: TFpDbgSymbol;
@ -3033,6 +3075,7 @@ destructor TFpDbgDwarfValue.Destroy;
begin
ReleaseRefAndNil(FTypeCastTargetType);
ReleaseRefAndNil(FTypeCastSourceValue);
SetLastMember(nil);
inherited Destroy;
end;
@ -3040,10 +3083,11 @@ procedure TFpDbgDwarfValue.SetValueSymbol(AValueSymbol: TDbgDwarfValueIdentifier
begin
if FValueSymbol = AValueSymbol then
exit;
if (FValueSymbol <> nil) and (RefCount >= 2) then
if CircleBackRefsActive and (FValueSymbol <> nil) then
FValueSymbol.ReleaseReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValueSymbol, 'TDbgDwarfSymbolValue'){$ENDIF};
FValueSymbol := AValueSymbol;
if (FValueSymbol <> nil) and (RefCount >= 2) then
if CircleBackRefsActive and (FValueSymbol <> nil) then
FValueSymbol.AddReference{$IFDEF WITH_REFCOUNT_DEBUG}(@FValueSymbol, 'TDbgDwarfSymbolValue'){$ENDIF};
end;
@ -3143,9 +3187,14 @@ begin
if (ti = nil) or not (ti.SymbolType = stType) then exit;
FValueObject := TDbgDwarfTypeIdentifier(ti).GetTypedValueObject(False);
FValueObject.MakePlainRefToCirclular;
if FValueObject <> nil then
FValueObject.SetValueSymbol(self);
// Used as reference to "self"
if StructureValueInfo <> nil then
FValueObject.SetStructureValue(TFpDbgDwarfValue(StructureValueInfo.Value)); // TODO: on request only
Result := FValueObject;
end;
@ -5345,6 +5394,7 @@ begin
if Result <> nil then exit;
FValueObject := TFpDbgDwarfValueEnumMember.Create(Self);
FValueObject.MakePlainRefToCirclular;
FValueObject.SetValueSymbol(self);
Result := FValueObject;
@ -5645,7 +5695,7 @@ end;
{ TDbgDwarfValueIdentifier }
procedure TDbgDwarfValueIdentifier.SetStructureValueInfo(AValue: TFpDbgSymbolBase);
procedure TDbgDwarfValueIdentifier.SetStructureValueInfo(AValue: TDbgDwarfIdentifier);
begin
if FStructureValueInfo = AValue then Exit;
@ -5809,7 +5859,8 @@ begin
FreeAndNil(FMembers);
if FValueObject <> nil then begin
FValueObject.SetValueSymbol(nil);
ReleaseRefAndNil(FValueObject);
FValueObject.ReleaseCirclularReference;
FValueObject := nil;
end;
ParentTypeInfo := nil;
inherited Destroy;
@ -6032,23 +6083,13 @@ begin
if not Result then
exit;
if (StructureValueInfo <> nil) and (ParentTypeInfo <> nil) then begin
if (AValueObj <> nil) and (AValueObj.StructureValue <> nil) and (ParentTypeInfo <> nil) then begin
Assert((ParentTypeInfo is TDbgDwarfIdentifier) and (ParentTypeInfo.SymbolType = stType), '');
if StructureValueInfo is TDbgDwarfValueIdentifier then begin
if TDbgDwarfValueIdentifier(StructureValueInfo).GetValueDataAddress(AValueObj, BaseAddr, TDbgDwarfTypeIdentifier(ParentTypeInfo)) then begin
ALocationParser.FStack.Push(BaseAddr, lseValue);
exit
end;
end
else
if StructureValueInfo is TFpDbgDwarfValueStructTypeCast then begin
if TFpDbgDwarfValueStructTypeCast(StructureValueInfo).GetDwarfDataAddress(BaseAddr, TDbgDwarfTypeIdentifier(ParentTypeInfo)) then begin
if AValueObj.StructureValue.GetDwarfDataAddress(BaseAddr, TDbgDwarfTypeIdentifier(ParentTypeInfo)) then begin
ALocationParser.FStack.Push(BaseAddr, lseValue);
exit
end;
end;
end;
debugln(FPDBG_DWARF_ERRORS, ['DWARF ERROR in TDbgDwarfIdentifierMember.InitLocationParser Error: ',ErrorCode(LastError),' ValueObject=', DbgSName(FValueObject)]);
if not IsError(LastError) then
@ -6064,17 +6105,7 @@ end;
function TDbgDwarfIdentifierMember.HasAddress: Boolean;
begin
Result := (FStructureValueInfo <> nil) and (FInformationEntry.HasAttrib(DW_AT_data_member_location));
if not Result then
exit;
if FStructureValueInfo is TDbgDwarfIdentifier then
Result := (TDbgDwarfIdentifier(FStructureValueInfo).HasAddress)
else
if FStructureValueInfo is TFpDbgValue then begin
Assert(FStructureValueInfo is TFpDbgDwarfValueStructTypeCast);
// Todo: move check to TDbgDwarfStructTypeCastSymbolValue
Result := TFpDbgDwarfValue(FStructureValueInfo).HasDwarfDataAddress;
end;
Result := (FInformationEntry.HasAttrib(DW_AT_data_member_location));
end;
{ TDbgDwarfIdentifierStructure }
@ -6949,7 +6980,7 @@ begin
Result := TDbgDwarfValueIdentifier.CreateValueSubClass('self', InfoEntry);
FSelfParameter := Result;
{$IFDEF WITH_REFCOUNT_DEBUG}FSelfParameter.DbgRenameReference(@FSelfParameter, 'FSelfParameter');{$ENDIF}
//FSelfParameter.ParentTypeInfo := Self;
//FSelfParameter.DbgSymbol.ParentTypeInfo := Self;
debugln(FPDBG_DWARF_SEARCH, ['TDbgDwarfProcSymbol.GetSelfParameter ', dbgs(InfoEntry.FScope, FCU), DbgSName(Result)]);
end;
end;