03 Virtual Machines


[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 Machines
2008 06 Virtual machines [Consumer test]
Measuring virtual machine detection in malware using DSD tracer
03 Virtual Memory?ches
03 Fuzzy Cognitive Maps Virtual Worlds
863 03
2002 09 Creating Virtual Worlds with Pov Ray and the Right Front End
ALL L130310?lass101
function virtual
Mode 03 Chaos Mode
2009 03 Our 100Th Issue
Simple State Machine Documentation
jezyk ukrainski lekcja 03
making vise clamps on the milling machine

więcej podobnych podstron