-
Notifications
You must be signed in to change notification settings - Fork 1
Sumários
Miguel Gamboa edited this page May 26, 2021
·
43 revisions
Aulas:
- 15-03-2021 - Lesson 00 - Introduction and planning
- 15-03-2021 - Lesson 01 - Modern VMs, e.g. JVM, CLR
- 15-03-2021 - Lesson 02 - Components and Metadata
- 17-03-2021 - Lesson 03 - Programming with Metadata (Cap 4.2 Essential .Net)
- 22-03-2021 - Lesson 04 - Programming with Metadata (Cap 4.2 Essential .Net)
- 22-03-2021 - Lesson 05 - Custom Attributes (Cap 4.4 Essential .Net)
- 24-03-2021 - Lesson 06 - Custom Attributes (Cap 4.4 Essential .Net)
- 31-03-2021 - Briefing on 1st Workout - FireMapper
- 07-04-2021 - Lesson 07 - Types at Runtime (Cap 4.1 Essential .Net)
- 12-04-2021 - Lab 1 on 1st Workout FireMapper
- 12-04-2021 - Lab 2 on 1st Workout FireMapper
- 14-04-2021 - Lab 3 on 1st Workout FireMapper
- 19-04-2021 - Lab 4 Validation on 1st Workout FireMapper
- 19-04-2021 - Lab 5 Validation on 1st Workout FireMapper
- 21-04-2021 - Lesson 13 - Reflection and Type System Exercises
-
26-04-2021 - Lesson 14 -
Log
--->
IGetter
- 26-04-2021 - Lesson 15 - Intermediate Language
-
28-04-2021 - Lesson 16 - Meta-programming and
System.Reflection.Emit
- 03-05-2021 - Lesson 17 - Meta-programming Logger
- 03-05-2021 - Lesson 18 - Meta-programming Logger
- 05-05-2021 - Lesson 19 - Meta-programming Logger
- 10-04-2021 - Lab 6 on 2nd Workout FireMapper
- 10-04-2021 - Lab 7 on 2nd Workout FireMapper
- 12-05-2021 - Lesson 22 - Instances (Chap 5 Instances - Essential .Net)
- 17-04-2021 - Lab 8 on 2nd Workout FireMapper
- 17-04-2021 - Lab 9 on 2nd Workout FireMapper
- 19-05-2021 - Lesson 25 - Methods (Chap 6 Methods - Essential .Net)
- 26-05-2021 - Lab 10 on 2nd Workout FireMapper
- 26-05-2021 - Lab 11 on 2nd Workout FireMapper
- 19-05-2021 - Lesson 28 - Benchmark performance evaluation
Reference: Essential .NET, Volume 1: The Common Language Runtime
- Assessments
- Bibliography
- Lecturing methodology: zoom, git and slack
- Tools: .Net SDK https://dotnet.microsoft.com/download
- SLIDES: isel-AVE-2021-week0-plan.pdf
- Virtual Execution Environment
- Informally virtual machine or runtime
- C# is NOT a goal
- Historic evolution since Java to .Net nowadays
- Examples of languages targeting JVM: Java, kotlin, Scala, Clojure
- Examples of languages targeting .Net: C#, F#, VB,
- C# essentials is equal to Java, E.g.
class A { static void foo() { }}
-
Component - Reusable software unit, with:
- IR - code in intermediate representation (e.g. bytecodes, IL, other)
- Metadata - auto description
- Ready to use
=>
does not require static compilation. - API
=>
conforms to a public interface. - Indivisible
=>
1 module (file)
-
Software development by Components:
- Reduce Complexity;
- Promote Reuse.
- Developer roles:
- Provider - provides a component with a well-known API (e.g.
Point
) - Client - uses the component from a provider to build an Application, or another component (e.g.
App
).
- Provider - provides a component with a well-known API (e.g.
-
Unmanaged
<versus>
Managed - Static
<versus>
Dynamic link
- Building unmanaged components with static link:
- NOT a unit, but two parts instead: header + obj
- Need of a header file that describes the component content
- Different builds for different architectures
-
Structural modifications (new header)
=>
compilation + link -
Behavioral modifications
=>
link
- Demo with an unmanaged
App
using aPoint
. - VS tools for C unmanaged:
-
cl /c
-- compile and produces an obj -
link comp1.obj comp2.lib etc
-- static link
-
- Demo with a managed
App
using aPoint
.- Jitter (just-in-time compiler) - compiles IR to native code (e.g. x86, amd64, ppc) at runtime
-
Dynamic link -
Point.class
onApp
compilation + link at runtime. -
Lazy Load -
Point.class
is loaded only when needed
- Solving TPC01
- Comparing Java components with Dotnet componentes:
.class
versus.dll
-
.class
with a single type -
.dll
with zero or more types
-
- Using Java disassemble tool:
javap -c ...
- Using Dotnet disassemble tool:
ildasm
- Highlight metadata and intermediate representation (bytecode or IL)
- Implicit definitions:
- default constructor:
<init>
(Java) and.ctor
(dotnet) - call base constructir:
invokespecial Object."<init>"
andcall Object::.ctor
- default constructor:
-
dependences
- Java classpath
- dotnet
.csproj
and reference to library
- Dotnet Type System -- CTS (Common Type System) ECMA 335
-
Reflection --
System.Reflection
in dotnet andjava.lang.reflect
in Java. - Reflection object oriented API for metadata
- Dotnet Reflection API (
System.Reflection
Namespace):Type
,FieldInfo
,MethodInfo
,ConstructorInfo
,PropertyInfo
,EventInfo
and abstract classMemberInfo
, which is the base type for aforementioned types. - Java Reflection API (
java.lang.reflect
):Class
,Member
,Method
eField
.
-
Type
is representing a type in Dotnet, whereasClass
is representing a type in Java. -
Assembly
is representing a component in Dotnet (.dll
) -
Assembly::LoadFrom(String path)
-- Static method returns anAssembly
instance for the component in givenpath
-
Assembly::GetTypes()
-- returns an array ofType
instances for all types in thatAssembly
instance (i.e. component).
- Homework:
-
Load(name)
versusLoadFrom(path)
-
fully qualified assembly name e.g.
"SampleAssembly, Version=1.0.2004.0, Culture=neutral, PublicKeyToken=8744b20f8da049e3"
-
GetTypes()
,GetMethods()
,MemberInfo.Name
-
- Dotnet solution and dependencies:
dotnet new sln
dotnet new classlib -o Logger
dotnet sln add Logger\Logger.csproj
dotnet new console -o App
dotnet sln add App\App.csproj
cd App
dotnet add reference ..\Logger\Logger.csproj
- Distinguishing the role of
App
--->
Logger
. - Version 1:
LogFields
andLogMethods
:-
FieldInfo::GetValue(object target)
; MethodInfo::Invoke(object, object[])
-
MethodInfo::GetParameters()
andParameterInfo
-
- Version 2:
LogMembers
- Java runtime type information –
Class
; - Dotnet runtime type information –
Type
; -
GetType()
returns the same object (same identity) for objects of the same class. - VM maintains a single info
Type
instance for each loaded type. -
getClass()
<=>
GetType()
-
p is Point
<=>
p instanceof Point
- C# operator
as
returnsnull
on unsuccess; - Cast throws exception on unsuccess;
- Unit tests franeworks, E.g. JUnit, TestNG, NUnit, XUnit, and others
dotnet new xunit
- How Unit tests franeworks distinguish test methods from others?
- By name prefix;
- By annotation, e.g.
@Test
,[Test]
,Fact
- AAA idiom: Arrange, Act and Assert
- How to test a void method like
Info()
? - Replace dependency
Log
---->
Console
with a newIPrinter
. -
Log
uses by default an instance ofConsolePrinter
, whereas unit tests use aBufferPrinter
to collect the output. - Augment
Logger
API to include aToLog
annotation that let clients select which members should be logged.
- .net
typeof(...)
<=>
Java.class
-
GetType()
vstypeof
-- run time<versus>
compile time -
Custom attributes usage:
- let developers annotate code, e.g.
[ToLog] string name; ...
- stored in metadata
- let developers annotate code, e.g.
- Defining new custom attribute: a class that extends
Attribute
- Inspecting custom attributes at runtime through the Reflection API:
Attribute::IsDefined(MemberInfo, Type) --> boolean
Attribute::GetCustomAttribute(MemberInfo, Type) --> object
MemberInfo::GetCustomAttributes(MemberInfo, Type) ---> object[]
-
Custom attributes with parameters. E.g:
class ToLogAttribute : Attribute { public ToLogAttribute(String label) { ...
- Usage:
[ToLog("Blue and White")] string name; ...
-
AttributeUsageAttribute
=> constraints ontarget
andAllowMultiple
, E.g:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple=true)]
public class ToLogAttribute : Attribute {
public ToLogAttribute(String label)
{
...
-
Logger
supporting Arrays -
Arrays are compatible with
IEnumerable
- Compatibility check alternatives:
typeof(IEnumerable).IsAssignableFrom(o.GetType())
o is IEnumerable ? Inspect((IEnumerable) o) : ...
IEnumerable seq = o as IEnumerable; ... seq != null ? Inspect(seq) : ...
- Details about IL operators
isinst
andcastclass
- Reflection API
IsSubclassOf
andIsAssignableFrom
- Overhead of
ShouldLog
with 4 verifications and anisinst
conversion:
if(!Attribute.IsDefined(m,typeof(ToLogAttribute))) return false;
if(m.MemberType == MemberTypes.Field) return true;
return m.MemberType == MemberTypes.Method && (m as MethodInfo).GetParameters().Length == 0;
- Refactor
Logger
to minimize the use of Reflection checks:- Keep
Dictionary<Type, List<MemberInfo>>();
- Keep
- Refactor Logger to avoid
if
/else
validation onLogMembers()
execution. - Drop
Dictionary<Type, IEnumerable<MemberInfo>>()
- Use
Dictionary<Type, IEnumerable<IGetter>>()
interface IGetter { string GetName(); object GetValue(object target);}
- Distinct implementations:
GetterField
,GetterMethod
, ... - Must use the same approach on FireMapper Workout with an interface specifying the way of dealing with properties
- Stack based execution model.
- Arguments and local variables tables.
- Operators
st...
andld...
. -
call
operator. - Compile with optimizations:
dotnet build -c release
- SLIDES: isel-AVE-2021-week5-IL
-
System.Reflection.Emit
:-
AssemblyBuilder
,ModuleBuilder
,TypeBuilder
,MethodBuidler
andILGenerator
-
- Following the example of defining a dynamic assembly with one module AssemblyBuilder
- Goal: Avoid Reflection on
IGetter
implementation:- Both
GetName()
andGetValue()
should not use the Reflection API.
- Both
- Define a new abstract class
GetterBase
with the implementation ofGetName()
from a literal:- The
GetValue()
remains abstract, for now.
- The
- Follow a use case of a derived class of
GetterBase
:- e.g. hard-coded
StudentNameGetter
to access the fieldname
- e.g. hard-coded
StudentNrGetter
to access the fieldnr
- e.g. hard-coded
-
Notice the difference between conversions:
-
string
--->
object
: implicit -
int
--->
object
: boxing corresponding tobox Int32
-
-
CreateIGetterFor(Type domain, String field)
that generates a dynamic implementation ofBaseGetter
for a given field in domain type. - Development approach:
- Use Reflection to emit IL and Do NOT emit IL that use Reflection
- First make a dummy hard-coded implementation that exemplifies the
dynamically generated class. E.g.
StudentNameGetter
,StudentNumberGetter
. Notice: these classes do not use Reflection - Compile those classes from 2. and check the resulting IL.
- Develop a dynamic builder that produces similar implementations to the IL from 3, i.e.
CreateIGetterFor
- Save the resulting
dll
and check its correctness throughPEVerify.exe
- Refactor
CreateIGetterFor
toCreateIGetterFor(Type domain, MemberInfo member)
; -
AbstractLog
with two implementations:Log
andLogDynamic
; -
AbstractLog
implementsLogMembers()
and has abstract methodGetMembers()
;
- Categories of Types: Value Types and Reference Types;
- Values versus Objects;
- Object layout;
- Object header:
sync#
andhtype
(Type Handle) - Runtime type information --
COREINFO_CLASS_STRUCT
- Value types extend from
System.ValueType
; - User-defined value types cannot be further extended.
-
Reference Types are instantiated in Csharp with
new
=>
ILnewobj
-
Value Types are NOT instantiated, but initialized instead:
- Invoking the parameterless constructor of a value type results in a
initobj
; -
initobj
initialize all fields with default values (0 ornull
).
- Invoking the parameterless constructor of a value type results in a
- Conversion Ref Type
<=>
Value Type -- boxing and unboxing. -
primitive types can be either Value Types or Reference Types, e.g.
int
,string
, etc. - !!! .Net:
int
<=>
System.Int32
-- there is NO conversion - !!! In Java:
int
!=
java.lang.Integer
-- there is boxing or unboxing.
- SLIDES: isel-AVE-2021-week7-instances
-
Reference Types are instantiated in C# through
new
=> ILnewobj
- Allocates storage on Heap
- Initializes space with zeros + Header (htype pointing to RTTI)
- Calls the constructor
- Returns the reference of newbie instance
-
Value tyoes are NOT instantiated but only initialized:
- Calling the parameterless constructor in C# results in
initobj
(initializes fields with0
/null
)
- Calling the parameterless constructor in C# results in
- Details about IL
ldloca
- Example with
ldloca
andinitobj
- e.g. Given
Point
as struct then callingnew Point(8, 9)
is NOTinitobj
butcall Point::ctor(...)
instead. - Structs cannot contain explicit parameterless constructors!
- Remember instance methods and virtual methods (
virtual
in C#). - Overriding methods require
override
keyword in C#. -
callvirt
not only for virtual methods, but also to call any instance methods on references. -
callvirt
performs an additional verification to check target (i.e.this
) is notnull
. - Value types does not require that verification because they are non-null.
- Instance methods on Value Types are called with
call
because they are non-virtual and their target cannot benull
.
- SLIDES: isel-AVE-2021-week7-instances
- Performance Evaluation and Benchmarking
- Benchmarking checks Performance != Unit tests checks correction
- E.g. Compare
Log
(Reflection) withLogDynamic
- Performance evaluation requirements:
- Focus on CPU bound operations
- Eliminate overheads, such as, initializing instances, setup, bootstrap, etc.
- Avoid IO operations, such as standard output, networking, etc...
- Reduce the VM side-effects
=>
execute many iterations
- Results approaches: Average, Standard deviation or the best result.
- Results units: Durations in milliseconds, seconds, whatever... or Throughput - number of operations in a time slot, e.g. ops/ms, ops/sec
- NBench - implementing a performance measure tool.