[MUSIC].
To close up this section, after we've
discussed how data is represented in in a
Java implementation and how procedures
are represented.Uh, we're now going to
talk about how we actually execute the
code.
And the runtime environment that Java
provides and a topic of virtual machines
that help us with this kind of code.
So, first let's let's talk about
implementing programming languages.
There's actually many choices to how to
implement programming models.
for the most part in this course, we've
talked about compilation.
taking a C program, compiling it into
assembly language instructions, which in
turn are further compiled into the actual
machine code that runs on our, on our
CPU.
But we can also interpret a language, and
by interpret we mean actually execute it
line by line in the original source code,
so we don't go through these extra
translation steps.
So this is obviously a lot less work for
the compiler to do.
In fact, we don't have a compiler at all,
we have an interpreter and all the work
is done at runtime.
This makes code a lot easier to debug
because we're always working off of the
source code.
We're not looking at a machine code
instructions or some believe, language
instructions that Lose a lot of the
context that we might have had in our
original code.
It's also easier to make languages run on
different architectures, because
essentially we're running the program in
a simulated environment that is part of
the interpretation of the languages.
So, rather than having to know what the
detailed instructions are that the CPU
can execute those machine code
instructions.
we can just interpret the language
directly.
Interpreted languages have a long, long
history, actually one of the first
programming languages called Lisp was an
interpreted language.
And there's still many interpreted
implementations very much with us today.
not only Java, but also Python,
JavaScript, Ruby, Matlab, a lot of
languages you might have heard of
mentioned.
So, there's actually a continuum from in,
fully interpreted languages like To
compile languages like C.
Java sits somewhere in the middle.
it's partly compiled and partly
interpreted, and what do we mean by that?
What we mean is that Java programs are
compiled into an intermediate language
that is run by a virtual machine.
It's not a real architecture; there's no
CPU.
That actually executes those
instructions, but it's very easy for us
to interpret those instructions on any
CPU.
So, it's kind of this intermediate level
of programming language.
A partly compiled language if you will.
And for Java it's called a bytecode
because it tries to pack Instructions
into single bytes.
Java can also be compiled ahead of time,
just like C is, and turned into a target
machine code for a particular CPU we
refer to those those are compilers and
they can be either at compile time, ahead
of time, or they can be just in time
compilers.
So if we look at this pictorially, we
have a high level language program
written in a language like Java, a native
machine language, the code, the machine
code and instructions for a particular
CPU And the virtual machine language sits
somewhere in the middle.
So we can have a Bytecode compiler that
turns our high level language into this
virtual machine language.
From there, we can go to different CPUs
for example, and easily re-target our
code.
That can be done we can do that using a
virtual machine interpreter or a JIT
compiler.
JIT remember stands for just in time.
the virtual machine interpreter is
actually going to look at the, at the
virtual machine language instructions,
the bytecodes.
And for each one, interpret it, decide
what it has to do.
the JIT compiler on the other hand, will
translate those instructions into the low
level native machine language.
And of course, we have the ahead of time
compiler that does that directly from the
high level language program.
So the reason for this virtual machine is
to create sort of a place where it's very
easy for us to compile or interpret to
different architectures.
That's what makes Java more portable.
All right, so let's focus in on the Java
virtual machine.
As we said, this is what makes Java more
machine independent than some other
languages.
The Java virtual machine also provides
some very strong protections for the
language that sort of keep people out of
trouble, programmers out of trouble,
unlike C which lets us run amok and do
anything we want with the memory of and,
and references into that memory.
Java uses a stack based execution model
and there are many different kinds of
Java virtual machines.
Some do more interpretation, some compile
the, into assembly.
they're usually implemented in a language
like C however.
So here's a model for the vitual machine.
in in most java virtual machines, there's
a concept of an operand stack where we
put operands that we're going to operate
on in our procedures and code.
And then a variable table where we can
store arguments and local variables.
typically, the zero element of the
variable table always holds a pointer to
the current object whose code we're
executing, so it would hold that pointer
to this, that, that the object in which
execution is currently.
then there's space for other arguments to
the method in the table and other local
variables that might be in that method.
Okay.
Let's take a look at a quick example.
Here's a Java bytecode for a very simple
operation namely taking two arguments
adding them together and And storing the
result.
So you'll see we have four byte codes
listed here.
looks kind of like assembly language, but
it's a, it's a little bit different.
You'll notice that there's no names for
registers.
what we're doing is just getting some
arguments and the first two instructions
and putting them on the stack.
we're pushing the first argument of our
function on to the stack, the second
argument and then we use an instruction
called add that pops the two elements
from the stack, adds them together,
pushes the result back on And then yet
another byte code called istore that
takes the result and puts it back into
the table at location number three and
that's the basics of byte codes.
No knowledge of registers, it just uses
those references into the Into the
variable table.
You'll also notice that these
instructions are pre-fixed with a letter
that signifies the data type that we're
working with.
so I stands for integer, A for reference
or address, B for byte, C for card, D for
double and so on, there's a few more but
that's basically it.
Four bytes, four instructions that tell
our virtual machine what to do.
So the C program that implements the
virtual machine, reads each one of these
bytes, and so oh, I load one.
That means it wants me to get an integer
from the variable table at location one
and place that on the stack, and just
proceeds along executing one byte code
after another.
If this were assembly language
instructions, we might have something
that looks like this.
You notice there's a lot more detail
here.
There's names of specific registers in
which to store things.
There are specific addresses where to, in
memory, when where, we have to go and put
and get those values that's not present
here.
Here we're dealing with just a stack in a
variable table all the locations are
implicit based on that.
And we're not worrying about addresses
and where things are.
We're leaving that up to the C program
that interprets those instructions to
design.
Here's a simple Java method this method
might be from a program that deals with a
database of employee names This method is
called get employee name and of it has no
arguments.
It's just going to be running in an
object that pro, has access to the name
of the employee and you'll notice that
the first bytecode is a reference load, a
load.
Get the value of this.
stored at variable at zero in the var
table.
And put that on the stack.
The next bytecodes is getfield.
It's as pop the stack.
go to that address.
offset it to the fifth field of the
object.
at that address, and there you'll find
the reference to a string for the name.
get that reference and put it back on the
stack.
All of that is done in that one byte code
instruction.
And then finally, the last instruction.
Is a return with an address value with a
reference value.
And it just pops the value that's
currently on the stack and returns that
as the return value of the procedure.
In this case, a reference to that
employee name.
So, that's the basic structure of a
method.
This URL at the bottom.
can point you to, it points you to all
the, the possible byte codes that might
exist for Java implementation.
This code occupies five bytes of memory.
A load is in the first byte, get field is
in the second byte.
Now get field is actually a byte code
that requires two more bytes.
To tell it which particular field in the
object to go get.
So these two bytes together are the
number five.
And then the last bytecode the return.
So they might be represented by these
codes.
This is what is in the Java class file
corresponding to this particular method.
The Java class file has everything that's
associated with a class in Java.
And there's ten sections actually to a
class file.
There's a magic number that starts things
off at the beginning.
a version of the format that's being used
just to keep things straight as Java's
updated.
a set of constant values that are
going to be used in this class.
some special flags to differentiate
whether this class or is abstract or
static.
the name of the, of the class, it's super
class that it inherits things from.
any interfaces it implements.
Then it's fields, it's methods, it's
attributes.
All of these are packaged together in a
single file.
The methods here are the ones that are
going to have the byte codes.
Corresponding to the code for each of the
methods in this class.
And this is packaged up into a JAR file
that collects all of the class files
associated with a Java program.
Give, given that we now have lots of Java
virtual machines up there many designers
have developed new languages.
That use the same byte codes as Java.
but totally different syntax.
So this is a list of some of the
languages, like AspectJ, and JRuby,
Jython Scala that are built on top of
Java virtual machines.
use Java bytecodes but are not Java
programs.
They're just using, exploiting that
intermediate language in order to compile
to that, and then have access to all the
machines on which these Java virtual
machines can run.
So this is another way that creating this
intermediate layer Has helped spur
language design in many different kinds
of languages for different tasks.
Microsoft C# and .NET Framework are
another example of these same concepts.
C# has a lot of the similar motivations
to Java and the virtual machine in this
case rather than being a JVM Is called
the common language runtime and theres a
common intermediate language that takes
the place of the bytecodes.
In the case of C# and just like in the
case of Java with many other languages
using the Java bytecodes there are many
languages that use the common
intermediate language or CIL that
Microsoft developed.
In this case things like J#, Visual Basic
are all languages that compile to the
same common intermediate language that
then is translated to the particular
machine and CPU that we want to run our
code on.
Wyszukiwarka
Podobne podstrony:
03 Virtual Machines2008 06 Virtual machines [Consumer test]Measuring virtual machine detection in malware using DSD tracer03 Virtual Memory?ches03 Fuzzy Cognitive Maps Virtual Worlds863 032002 09 Creating Virtual Worlds with Pov Ray and the Right Front EndALL L130310?lass101function virtualMode 03 Chaos Mode2009 03 Our 100Th IssueSimple State Machine Documentationjezyk ukrainski lekcja 03making vise clamps on the milling machinewięcej podobnych podstron