-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmini-jvm.drawio
396 lines (396 loc) · 104 KB
/
mini-jvm.drawio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
<mxfile host="Electron" modified="2024-04-19T15:56:49.815Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.5 Chrome/114.0.5735.243 Electron/25.3.1 Safari/537.36" etag="8etbdHrPRuGhRPIH-kHP" version="21.6.5" type="device">
<diagram name="第 1 页" id="_ELyFHzvFEiwb_eeZEqK">
<mxGraphModel dx="3341" dy="1034" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="eWhodD4vRtD6RhS1Q6ua-54" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">main(String[] args) 方法体<br style="font-size: 10px;">{</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; System.out.println("hello");</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">}</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">被编译为下面4条字节码指令:</font></div><div style=""><font color="#007fff" style=""><div style="font-size: 10px;">&nbsp;GETSTATIC java/lang/System.out : Ljava/io/PrintStream;<span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><b>//即从 java/lang/System 类中获取 out 静态字段 返回为 PrintStream 类型</b></div><div style="font-size: 10px;">&nbsp;LDC "hello"</div><div style="font-size: 10px;">&nbsp;INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V<span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><b style="background-color: initial; border-color: var(--border-color);">//即调用 java/io/PrintStream println(Ljava/lang/String;)V 方法</b></div></font><font color="#007fff" style=""><div style="font-size: 10px;">&nbsp;<span style="background-color: initial;">RETURN</span></div><div style="font-size: 10px;"><span style="background-color: initial;"><br></span></div><div style=""><div style="">{Integer@1734} 0 -&gt; {<b>GetStaticInst</b>@1735} "GetStaticInst{clazz='java/lang/System', fieldName='out', fieldDescriptor='Ljava/io/PrintStream;'}"</div><div style="">&nbsp;key = {Integer@1734} 0</div><div style="">&nbsp;value = {GetStaticInst@1735} "GetStaticInst{clazz='java/lang/System', fieldName='out', fieldDescriptor='Ljava/io/PrintStream;'}"</div><div style="">&nbsp; <b>clazz</b> = "java/lang/System"</div><div style="">&nbsp; <b>fieldName</b> = "out"</div><div style="">&nbsp; <b>fieldDescriptor</b> = "Ljava/io/PrintStream;"</div><div style="">{Integer@1736} 3 -&gt; {<b>LdcInst</b>@1737} "LdcInst{descriptor='Ljava/lang/String', val=hello}"</div><div style="">&nbsp;key = {Integer@1736} 3</div><div style="">&nbsp;value = {LdcInst@1737} "LdcInst{descriptor='Ljava/lang/String', val=hello}"</div><div style="">&nbsp; <b>descriptor</b> = "Ljava/lang/String"</div><div style="">&nbsp; <b>val</b> = "hello"</div><div style="">{Integer@1738} 5 -&gt; {<b>InvokeVirtualInst</b>@1739} "InvokeVirtualInst{clazz='java/io/PrintStream', methodName='println', methodDescriptor='(Ljava/lang/String;)V'}"</div><div style="">&nbsp;key = {Integer@1738} 5</div><div style="">&nbsp;value = {InvokeVirtualInst@1739} "InvokeVirtualInst{clazz='java/io/PrintStream', methodName='println', methodDescriptor='(Ljava/lang/String;)V'}"</div><div style="">&nbsp; <b>clazz</b> = "java/io/PrintStream"</div><div style="">&nbsp; <b>methodName</b> = "println"</div><div style="">&nbsp; <b>methodDescriptor</b> = "(Ljava/lang/String;)V"</div><div style="">{Integer@1740} 8 -&gt; {ReturnInst@1741}&nbsp;</div></div><div style="font-size: 10px;"><br></div></font></div>" style="text;html=1;align=left;verticalAlign=top;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1480" y="2040" width="730" height="360" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-1" value="<h1 style="font-size: 18px;"><font style="font-size: 18px;">Mini-jvm 工作原理</font></h1><div style=""><div style=""><font style="font-size: 12px;">参考 Java8 HotSpot 实现的开源的简单的JVM实现,jvm-core 除去 Instuction (字节码指令实现) 也就剩下大概 7K多行,很容易理解。<br>不过功能也只包含一些很核心的功能。</font></div><div style=""><font style="font-size: 12px;">https://github.com/guxingke/mini-jvm</font><br></div></div>" style="text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;fontSize=16;" parent="1" vertex="1">
<mxGeometry x="40" y="10" width="760" height="90" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-2" target="hw3rN0ojpoE_x7gTb8zc-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-2" value="Main#main(String[] args)<br><font color="#007fff">位于jvm-core模块</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="40" y="120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-6" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-3" target="hw3rN0ojpoE_x7gTb8zc-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-25" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-3" target="hw3rN0ojpoE_x7gTb8zc-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-3" value="Args cmd = Args.parseArgs(args);<br><div><font color="#007fff">主要是解析 -cp -jar 获取类加载路径</font></div><div><font color="#007fff">以及获取Main类全限定名</font></div>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="280" y="120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-9" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-5" target="hw3rN0ojpoE_x7gTb8zc-8" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-5" value="VirtualMachine vm = new <b>VirtualMachine</b>();<br><font color="#007fff">这个类并没有任何成员字段</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="280" y="220" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-7" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Args</b></p><hr size="1"><p style="margin:0px;margin-left:4px;">boolean version;</p><p style="margin:0px;margin-left:4px;">boolean help;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//是否启用详细日志输出,打开的话会输出详细的运行日志</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//作者支持了trace call class debug</font></p><p style="margin:0px;margin-left:4px;">boolean <b>verbose</b>;</p><p style="margin:0px;margin-left:4px;">boolean verboseTrace;</p><p style="margin:0px;margin-left:4px;">boolean verboseCall;</p><p style="margin:0px;margin-left:4px;">boolean verboseClass;</p><p style="margin:0px;margin-left:4px;">boolean verboseDebug;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//解析 -cp -jar 参数获取到的类路径</font></p><p style="margin:0px;margin-left:4px;">public String <b>classpath</b> = ".";</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//应用的Main类全限定名</font></p><p style="margin:0px;margin-left:4px;">public String <b>clazz</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//原始参数列表</font></p><p style="margin:0px;margin-left:4px;">public String[] <b>args</b> = new String[0];</p><hr size="1"><p style="margin:0px;margin-left:4px;">public static Args <b>parseArgs</b>(String... cliArgs)<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-400" y="120" width="360" height="280" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-8" target="hw3rN0ojpoE_x7gTb8zc-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-8" value="vm.<b>run</b>(cmd);" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="280" y="320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-14" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-10" target="hw3rN0ojpoE_x7gTb8zc-13" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-10" value="先将 Args 对象的参数再记录到 EnvHolder 中" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="520" y="320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-12" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>EnvHolder</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;">public static boolean verbose;</p><p style="margin:0px;margin-left:4px;">public static boolean verboseTrace;</p><p style="margin:0px;margin-left:4px;">public static boolean verboseCall;</p><p style="margin:0px;margin-left:4px;">public static boolean verboseClass;</p><p style="margin:0px;margin-left:4px;">public static boolean verboseDebug;</p><p style="margin:0px;margin-left:4px;">public static boolean debug;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-800" y="120" width="360" height="160" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-16" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-13" target="hw3rN0ojpoE_x7gTb8zc-15" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-13" value="Entry entry = Classpath.parse(Utils.classpath(<br>cmd.classpath));<br><font style="font-size: 10px;" color="#007fff">先获取类路径,再解析类路径到Entry实例</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="520" y="400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-15" target="hw3rN0ojpoE_x7gTb8zc-17" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-32" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-15" target="hw3rN0ojpoE_x7gTb8zc-31" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-15" value="ClassLoader classLoader = new <b>ClassLoader</b>("boot", entry);<br><b>initVm</b>(classLoader);<br><font color="#007fff">创建boot类加载器,初始化JVM</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="520" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-20" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-17" target="hw3rN0ojpoE_x7gTb8zc-19" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-62" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-17" target="hw3rN0ojpoE_x7gTb8zc-61" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-17" value="<div>String mainClass = Utils.replace(<br>cmd.clazz, '.', EnvHolder<br>.FILE_SEPARATOR.toCharArray([0]);<span style="background-color: initial;">&nbsp; &nbsp; classLoader.<b>loadClass</b>(mainClass);</span></div><div><font color="#007fff">主类的类加载</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="520" y="1320" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-22" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-19" target="hw3rN0ojpoE_x7gTb8zc-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-19" value="Class clazz = Heap.findClass(mainClass);<br>Method method = clazz.getMainMethod();<br><font color="#007fff">查找应用程序Main类的main()方法</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="520" y="1640" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-21" target="eWhodD4vRtD6RhS1Q6ua-14">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-21" value="Interpreter.<b>runMain</b>(method, cmd.args);<br><font color="#007fff">解析器执行main()方法</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="520" y="1860" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-24" value="args.clazz = parseMainClass(jar);<br><font color="#007fff">解析Java包中的Main类:通过解析META-INF/MANIFEST.MF文件中 Main-Class属性获取</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="520" y="120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-26" value="<font color="#007fff">比如测试中最终引入的类路径(可以看到将JDK的jar包也都引进来了,因为mini-jvm并没有实现多少JDK上的实现):&nbsp;<br>example:/home/arvin/mywork/github/mini-jvm/mini-jdk/target/rt.jar:/home/arvin/.jabba/jdk/[email protected]/jre/lib/*<br>此时 Entry 是 CompositeEntry 类型<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="730" y="400" width="650" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-27" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Entry (I)</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">类搜索接口,有3种实现,DirEntry JarEntry CompositeEntry</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">实现类也是 classPath 的容器</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;">ClassFile findClass(String name);<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-400" y="440" width="360" height="130" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-28" value="<div style="font-size: 10px;"><font style="font-size: 10px;">entries = {ArrayList@508}&nbsp; size = 3</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;0 = {<b>DirEntry</b>@515}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; dirPath = "example"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;1 = {<b>JarEntry</b>@518}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; path = "/home/arvin/mywork/github/mini-jvm/mini-jdk/target/rt.jar"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;2 = {<b>CompositeEntry</b>@521}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; entries = {ArrayList@525}&nbsp; size = 7</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;0 = {<b>JarEntry</b>@527}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;1 = {JarEntry@528}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;2 = {JarEntry@529}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;3 = {JarEntry@530}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;4 = {JarEntry@531}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;5 = {JarEntry@532}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; &nbsp;6 = {JarEntry@533}&nbsp;</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-710" y="440" width="310" height="180" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-30" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ClassLoader</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">类加载器实现,只实现最核心的功能,没有实现双亲委托等功能</font></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;">private final String <b>name</b>;</p><p style="margin:0px;margin-left:4px;">private final Entry <b>entry</b>;</p><hr size="1"><p style="margin:0px;margin-left:4px;">public void loadPrimitiveClass(String name)<br></p><p style="margin:0px;margin-left:4px;">public void loadPrimitiveArrayClass(String name)<br></p><p style="margin:0px;margin-left:4px;">public Class loadClass(String name)<br></p><p style="margin:0px;margin-left:4px;">public void doRegister(Class clazz)<br></p><p style="margin:0px;margin-left:4px;">public Class doLoadClass(String name)<br></p><p style="margin:0px;margin-left:4px;">public Class doLoadClass(String name, ClassFile classFile)<br></p><p style="margin:0px;margin-left:4px;">public Method map(MethodInfo cfMethodInfo)<br></p><p style="margin:0px;margin-left:4px;">public Field map(FieldInfo fieldInfo)<br></p><p style="margin:0px;margin-left:4px;">public String getName()<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-400" y="600" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-34" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-31" target="hw3rN0ojpoE_x7gTb8zc-33" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-31" value="MetaSpace.main = new Thread(1024);<br><font color="#007fff">创建一个栈帧容器,最大栈深1024</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-36" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-33" target="hw3rN0ojpoE_x7gTb8zc-35" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-45" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-33" target="hw3rN0ojpoE_x7gTb8zc-44" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-33" value="<b>loadLibrary</b>();<br><font style="font-size: 10px;" color="#007fff">注册了一组<b>本地方法</b>到堆,不过它内部并不是通过JNI链接到系统调用,而是直接链接到了官方的JDK的本地方法</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-38" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-35" target="hw3rN0ojpoE_x7gTb8zc-37" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-35" target="hw3rN0ojpoE_x7gTb8zc-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-35" value="<b>loadFoundationClass</b>(classLoader);<br><font color="#007fff">加载基础类型,java/lang/Class、8中基本类型及器对应的包装类型、数组类型、String、Void</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="850" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-37" value="initSystemOut(classLoader);<br>initSystemErr(classLoader);<br><font color="#007fff" style="font-size: 10px;">加载 FileDescriptor、FileOutputStream、PrintStream、System</font>" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="1000" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-42" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=open;endFill=0;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-39" target="hw3rN0ojpoE_x7gTb8zc-40" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-39" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>MateSpace</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">元空间,对标的HotSpot中的元空间</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//栈帧容器</font></p><p style="margin:0px;margin-left:4px;">public static Thread <b>main</b>;<br></p><hr size="1"><p style="margin:0px;margin-left:4px;">public static Thread getMainEnv()</p><p style="margin:0px;margin-left:4px;">public static NativeMethod findNativeMethod(String key)<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-400" y="880" width="360" height="160" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-43" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=open;endFill=0;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-40" target="hw3rN0ojpoE_x7gTb8zc-41" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-40" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Thread</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">内部线程,是一个栈结构,看它的源码实现这其实是栈帧的容器</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//top其实是栈帧数量,top-1是栈顶的索引</font></p><p style="margin:0px;margin-left:4px;">public int top;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//保存栈帧的栈</font></p><p style="margin:0px;margin-left:4px;">public Frame[] frames;</p><hr size="1"><p style="margin:0px;margin-left:4px;">public void pushFrame(Frame frame)&nbsp;<br></p><p style="margin:0px;margin-left:4px;">public Frame popFrame()<br></p><p style="margin:0px;margin-left:4px;">public Frame topFrame()<br></p><p style="margin:0px;margin-left:4px;">public Frame callerFrame()<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-800" y="880" width="360" height="200" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-17" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-41" target="eWhodD4vRtD6RhS1Q6ua-16">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-41" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Frame</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff"><b>栈帧</b></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//当前栈帧执行的方法</font></p><p style="margin:0px;margin-left:4px;">public final Method <b>method</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//本地变量列表, LocalVars 是 Slot 数组</font></p><p style="margin:0px;margin-left:4px;">private final LocalVars <b>localVars</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//操作数栈,是 Slot 栈,除了Slot数组还包含一个top(栈顶索引)</font></p><p style="margin:0px;margin-left:4px;">private final OperandStack <b>operandStack</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//com.gxk.jvm.rtda.heap.</font><font color="#007fff">Method的 instructionMap</font></p><p style="margin:0px;margin-left:4px;">private final Map&lt;Integer, Instruction&gt; <b>instructionMap</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//即MetaSpace栈帧容器main</font></p><p style="margin:0px;margin-left:4px;">public final Thread <b>thread</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//下一个指令的程序计数器值</font></p><p style="margin:0px;margin-left:4px;">public int <b>nextPc</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//当前指令的程序计数器值</font></p><p style="margin:0px;margin-left:4px;">private int <b>pc</b>;</p><p style="margin:0px;margin-left:4px;">public int <b>stat</b>;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1200" y="830" width="360" height="300" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-44" value="<div style="font-size: 10px;">ObjectBridge.registerNatives0();</div><div style="font-size: 10px;">ClassBridge.registerNatives0();</div><div style="font-size: 10px;">SystemBridge.registerNatives0();</div><div style="font-size: 10px;">FileOutputStreamBridge.registerNatives0();</div><div style="font-size: 10px;">FileDescriptorBridge.registerNative0();</div><div style="font-size: 10px;">MathBridge.registerNatives0();</div><div style="font-size: 10px;">UnsafeBridge.registerNatives0();</div><div style="font-size: 10px;">IntegerBridge.registerNatives0();</div><div style="font-size: 10px;">FloatBridge.registerNatives0();</div><div style="font-size: 10px;">DoubleBridge.registerNatives0();</div><div style="font-size: 10px;">StringBridge.registerNatives0();</div><div style="font-size: 10px;">RandomBridge.registerNatives0();</div><div style="font-size: 10px;">ExceptionBridge.registerNatives0();</div><div style="font-size: 10px;">ThrowableBridge.registerNatives0();</div><div style="font-size: 10px;">AtomicLongBridge.registerNatives0();</div><div style="font-size: 10px;">ReflectionBridge.registerNatives0();</div><div style="font-size: 10px;">ClassLoaderBridge.registerNatives0();</div><div style="font-size: 10px;">AccessControllerBridge.registerNative0();</div><div style="font-size: 10px;">PropertiesBridge.registerNative0();</div><div style="font-size: 10px;">CharsetBridge.registerNative0();</div><div style="font-size: 10px;">UnixFileSystemBridge.registerNatives0();</div><div style="font-size: 10px;">FileInputStreamBridge.registerNatives0();</div><div style="font-size: 10px;">ZipFileBridge.registerNatives0();</div><div style="font-size: 10px;">NativeInputStreamBridge.registerNatives0();</div><div style="font-size: 10px;"><font color="#007fff">注册了一些常用的类的本地方法</font></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;fontSize=10;arcSize=2;" parent="1" vertex="1">
<mxGeometry x="1001" y="480" width="240" height="300" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-18" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=open;endFill=0;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-46" target="hw3rN0ojpoE_x7gTb8zc-49">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-46" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Heap</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">堆空间,对标的HotSpot中的堆</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//本地方法的Map</font></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">private static final Map&lt;String, </span><b style="font-size: 11px;">NativeMethod</b><span style="font-size: 11px;">&gt; </span><font style="font-size: 10px;">NATIVE_METHOD_MAP</font><span style="font-size: 11px;">;</span><br></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;"><font color="#007fff">// Klass的Map</font></p><p style="margin: 0px 0px 0px 4px; font-size: 11px;">private static final Map&lt;String, <b>Class</b>&gt; <font style="font-size: 11px;">STRING_K_CLASS_MAP</font>;<br></p><hr size="1"><p style="margin:0px;margin-left:4px;">public static void registerMethod(String key, NativeMethod method)<br></p><p style="margin:0px;margin-left:4px;">public static NativeMethod findMethod(String key)<br></p><p style="margin:0px;margin-left:4px;">public static Class findClass(String name)<br></p><p style="margin:0px;margin-left:4px;">public static void registerClass(String name, Class clazz)<br></p><p style="margin:0px;margin-left:4px;">public static List&lt;Class&gt; getClasses()<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-800" y="1160" width="360" height="200" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-52" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-47" target="hw3rN0ojpoE_x7gTb8zc-51" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-47" value="<font color="#007fff">//加载官方JDK中的Class类<br></font>Class metaClass = classLoader<br>.<b>loadClass</b>("java/lang/Class");<br><font color="#007fff">//遍历Heap中注册的类名,依次进行实例化<br></font><div>for (Class cls : Heap.getClasses()) {</div><div>&nbsp; &nbsp; if (cls.getRuntimeClass() == null) {</div><div>&nbsp; &nbsp; Instance obj = metaClass.<b>newInstance</b>();</div><div>&nbsp; &nbsp; cls.setRuntimeClass(obj);</div><div>&nbsp; &nbsp; obj.setMetaClass(cls);</div><div>&nbsp; &nbsp; }</div><div>}</div>" style="rounded=1;whiteSpace=wrap;html=1;arcSize=4;align=left;" parent="1" vertex="1">
<mxGeometry x="1001" y="800" width="239" height="160" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-20" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=open;endFill=0;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-49" target="eWhodD4vRtD6RhS1Q6ua-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-21" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=open;endFill=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-49" target="eWhodD4vRtD6RhS1Q6ua-6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-49" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Class</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">对标HotSpot中的<b>Klass</b>类(保存JVM中类元数据),每个类加载后都有一个Klass</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">注意区分官方JDK中<b>Class</b>与<b>Klass</b></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><b>Mini-JVM 使用自定义的 Class 作为 Klass,还是使用官方JDK的Class作为反射接口</b></font></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;"><br></span></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;">public final int accessFlags;</span><br></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final String name;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final String superClassName;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final List&lt;String&gt; interfaceNames;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final List&lt;Method&gt; methods;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final List&lt;Field&gt; fields;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final BootstrapMethods bootstrapMethods;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final ConstantPool constantPool;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;"><font color="#007fff">//该类实例的的类加载器</font></span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final ClassLoader classLoader;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public final ClassFile classFile;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;"><br></span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">private Class <b>superClass</b>;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">private List&lt;Class&gt; <b>interfaces</b>;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;"><font color="#007fff">//初始状态为0, 检查存在静态初始化方法&lt;clinit&gt;后为1, 执行静态初始化方法后为2,</font></span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;"><font color="#007fff">//只要有静态成员初始化或静态代码块就会自动生成 clinit 方法</font></span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">public int <b>stat</b> = 0;</span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;"><br></span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;"><font color="#007fff">//即官方JDK中的Class对象</font></span></p><p style="margin: 0px 0px 0px 4px;"><span style="font-size: 11px;">private Instance runtimeClass;</span></p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-1200" y="1160" width="360" height="440" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-50" value="<font color="#cc0000">为何要单独注册下本地方法?</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="520" y="540" width="180" height="30" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-54" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-51" target="hw3rN0ojpoE_x7gTb8zc-53" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-51" value="classLoader.<b>loadPrimitiveClass</b>(...)<br>加载 char、boolean、byte、... 八种基本类型,以及 void 类型" style="rounded=1;whiteSpace=wrap;html=1;arcSize=17;align=left;" parent="1" vertex="1">
<mxGeometry x="1001" y="980" width="239" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-58" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-53" target="hw3rN0ojpoE_x7gTb8zc-57" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-53" value="classLoader.<b>loadClass</b>(...)<br>加载 char、boolean、byte、... 八种基本类型的包装类型,以及 String、Void 类型" style="rounded=1;whiteSpace=wrap;html=1;arcSize=17;align=left;" parent="1" vertex="1">
<mxGeometry x="1001" y="1060" width="239" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-57" value="<div>classLoader.<b>loadPrimitiveArrayClass</b>(...)</div><div>加载 char、boolean、byte、... 八种基本类型的数组类型</div>" style="rounded=1;whiteSpace=wrap;html=1;arcSize=17;align=left;" parent="1" vertex="1">
<mxGeometry x="1001" y="1140" width="239" height="60" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-64" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-61" target="hw3rN0ojpoE_x7gTb8zc-63" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-66" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="hw3rN0ojpoE_x7gTb8zc-61" target="hw3rN0ojpoE_x7gTb8zc-65" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-61" value="Class clazz = doLoadClass(name);<br><font color="#007fff">先查看下堆中这个类是否已经存在,不存在则加载并注册到堆中</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="760" y="1330" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-12" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-63" target="eWhodD4vRtD6RhS1Q6ua-11">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-63" value="doRegister(clazz);<br><font style="font-size: 10px;" color="#007fff">就是将新实例化的&nbsp;com.gxk.jvm.rtda.heap.Class 注册到堆空间 STRING_K_CLASS_MAP,并检查和它对应的本地方法是否存在</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="760" y="1520" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-23" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-65" target="eWhodD4vRtD6RhS1Q6ua-22">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-26" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="eWhodD4vRtD6RhS1Q6ua-23">
<mxGeometry x="0.9241" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-24" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="hw3rN0ojpoE_x7gTb8zc-65" target="eWhodD4vRtD6RhS1Q6ua-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-25" value="2" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="eWhodD4vRtD6RhS1Q6ua-24">
<mxGeometry x="0.45" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="hw3rN0ojpoE_x7gTb8zc-65" value="<div style="font-size: 11px;"><font color="#007fff">//1 先查找类名对应在Entry中的class文件,<b>class文件内容读取到ClassFile实例</b></font></div><div style="font-size: 11px;">ClassFile clazz = entry.<b>findClass</b>(name);</div><div style="font-size: 11px;"><font color="#007fff">//2&nbsp;<b>执行类加载</b>,这个Class对标的HotSpot <b>Klass</b></font></div><div style="font-size: 11px;">Class aClass = <b>doLoadClass</b>(name, clazz);</div><div style="font-size: 11px;"><span style="background-color: initial;"><font color="#007fff">//如果类有超类,则加载超类</font></span></div><div style="font-size: 11px;"><span style="background-color: initial;">if (aClass.superClassName != null) {</span><br></div><div style="font-size: 11px;">&nbsp; &nbsp; aClass.<b>setSuperClass</b>(this.<b>loadClass</b>(</div><div style="font-size: 11px;">aClass.superClassName));</div><div style="font-size: 11px;">}</div><div style="font-size: 11px;"><span style="background-color: initial;"><br></span></div><div style="font-size: 11px;"><span style="background-color: initial;">if (Heap.findClass("java/lang/Class") != null) {</span><br></div><div style="font-size: 11px;">&nbsp; &nbsp; Instance rcs = Heap.findClass("java/lang/Class")<span style="background-color: initial;">.newInstance();</span></div><div style="font-size: 11px;"><span style="background-color: initial;"><font color="#007fff">&nbsp; &nbsp; //Klass 与 Class 相互引用</font></span></div><div style="font-size: 11px;">&nbsp; &nbsp; aClass.<b>setRuntimeClass</b>(rcs);</div><div style="font-size: 11px;">&nbsp; &nbsp; rcs.<b>setMetaClass</b>(aClass);</div><div style="font-size: 11px;">}</div><div style="font-size: 11px;">return aClass;</div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;arcSize=3;fontSize=11;" parent="1" vertex="1">
<mxGeometry x="1001" y="1225" width="239" height="270" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-59" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;endArrow=open;endFill=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-1" target="eWhodD4vRtD6RhS1Q6ua-32">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-1" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ClassFile</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">.class文件读取后的文件对象实例</font></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//魔数,确认是否能让虚拟机接受的class文件 在java中 通常为0xCAFEBABE</font></p><p style="margin:0px;margin-left:4px;">public final int magic;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//jvm的次版本号</font></p><p style="margin:0px;margin-left:4px;">public final int minorVersion;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//jvm的主版本号</font></p><p style="margin:0px;margin-left:4px;">public final int majorVersion;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//常量池大小 用来解析后面的常量池</font></p><p style="margin:0px;margin-left:4px;">public final int constantPoolSize;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//常量池结构</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//其中类如果没写继承任何其他类则默认继承Object</font></p><p style="margin:0px;margin-left:4px;">public final ConstantPool <b>cpInfo</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//类访问标志,16位的“bitmask”指出class文件定义的是类还是接口,</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">访问级别是public还是private,</font></p><p style="margin:0px;margin-left:4px;">public final int <b>accessFlags</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//类索引(是常量池索引),class文件存储的类名类似完全限定名</font></p><p style="margin:0px;margin-left:4px;">public final int thisClass;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//父类索引,同上</font></p><p style="margin:0px;margin-left:4px;">public final int <b>superClass</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//接口索引数</font></p><p style="margin:0px;margin-left:4px;">public final int interfacesCount;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//接口索引表,给出该类实现的所有接口的名字</font></p><p style="margin:0px;margin-left:4px;">public final Interfaces interfaces;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//字段数</font></p><p style="margin:0px;margin-left:4px;">public final int fieldCount;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//字段结构,存储字段信息</font></p><p style="margin:0px;margin-left:4px;">public final Fields fields;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//方法数</font></p><p style="margin:0px;margin-left:4px;">public final int methodsCount;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//方法结构,存储方法信息</font></p><p style="margin:0px;margin-left:4px;">public final Methods methods;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//属性数</font></p><p style="margin:0px;margin-left:4px;">public final int attributesCount;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//属性结构,存储属性信息,</font><font color="#007fff">比如源码文件名(SourceFile)、</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">代码属性(Code)、异常处理表、行号表、局部变量表、常量表、</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">注解属性等</font></p><p style="margin:0px;margin-left:4px;">public final Attributes <b>attributes</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//class文件路径</font></p><p style="margin:0px;margin-left:4px;">private String source;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-400" y="1160" width="360" height="640" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-8" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-3" target="eWhodD4vRtD6RhS1Q6ua-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-3" value="ClassLoader#<b>doLoadClass</b>(String name, ClassFile classFile);<br><font color="#007fff" style="font-size: 10px;">就是解析ClassFile内容转成对应类实例,比如方法-&gt;Method,字段-&gt;Field,超类接口等<br>最终创建 <b>Class</b> 对象实例<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="1280" y="1320" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-5" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Method</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">对标HotSpot的<b>KMethod</b>类</font></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//方法的访问标志,如public private,</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">其中&amp;0x0100这位表示是否是本地方法</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">&amp;0x0008这位表示是否是静态方法<br></font></p><p style="margin:0px;margin-left:4px;">public final int <b>accessFlags</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//方法名</font></p><p style="margin:0px;margin-left:4px;">public final String <b>name</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//参数以及返回值类型</font></p><p style="margin:0px;margin-left:4px;">public final String <b>descriptor</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//操作数栈最大size</font></p><p style="margin:0px;margin-left:4px;">public final int maxStacks;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//本地变量表最大长度</font></p><p style="margin:0px;margin-left:4px;">public final int maxLocals;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//指令Map,就是代码块中包含的字节码指令Map</font></p><p style="margin:0px;margin-left:4px;">public final Map&lt;Integer, Instruction&gt; <b>instructionMap</b>;</p><p style="margin:0px;margin-left:4px;">public final ExceptionTable exceptionTable;</p><p style="margin:0px;margin-left:4px;">public final LineNumberTable lineNumberTable;</p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;">public Class clazz;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1600" y="1160" width="360" height="360" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-6" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Field</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">对标官方JDK的<b>KField</b>类</font></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;"><br></span></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;"><font color="#007fff">//字段的访问标志,如public private,<br></font></span></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;"><font color="#007fff">其中</font></span><font color="#007fff">&amp;0x0008这位表示是否是静态字段</font></p><p style="margin:0px;margin-left:4px;">public final int accessFlags;</p><p style="margin:0px;margin-left:4px;">public final String name;</p><p style="margin:0px;margin-left:4px;">public final String descriptor;</p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;"></span></p><p style="margin:0px;margin-left:4px;">public UnionSlot val;</p><p style="margin:0px;margin-left:4px;"><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1600" y="1560" width="360" height="200" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-7" value="<div style="font-size: 11px;"><span style="background-color: initial; font-size: 11px;"><font color="#007fff" style="font-size: 11px;">//MethodInfo -&gt; Method</font></span></div><div style="font-size: 11px;"><span style="background-color: initial; font-size: 11px;">methods.add(this.</span><b style="background-color: initial; font-size: 11px;">map</b><span style="background-color: initial; font-size: 11px;">(methodInfo));</span></div><div style="font-size: 11px;">...</div><div style="font-size: 11px;"><font color="#007fff" style="font-size: 11px;">//FieldInfo -&gt; Field</font></div>fields.add(this.map(fieldInfo));<br style="font-size: 11px;">...<br style="font-size: 11px;"><font color="#007fff" style="font-size: 11px;">//执行字段的静态初始化方法<br style="font-size: 11px;"></font><div style="font-size: 11px;">for (Field it : fields) {</div><div style="font-size: 11px;">&nbsp; if (it.isStatic()) {</div><div style="font-size: 11px;">&nbsp; &nbsp; it.<b>init</b>();</div><div style="font-size: 11px;">&nbsp; }</div><div style="font-size: 11px;">}</div><div style="font-size: 11px;">...</div><div style="font-size: 11px;"><font color="#007fff" style="font-size: 11px;">//超类类名(常量池中索引scIdx位置),这里可以看到Java只能单继承</font></div><div style="font-size: 11px;">superClassName = Utils.getClassName(classFile.cpInfo, scIdx);<br style="font-size: 11px;"></div><div style="font-size: 11px;">...</div><div style="font-size: 11px;"><font color="#007fff" style="font-size: 11px;">//实现的接口类名</font></div><div style="font-size: 11px;">interfaceNames.add(anInterface.getName());<br style="font-size: 11px;"></div><div style="font-size: 11px;">...</div><div style="font-size: 11px;">BootstrapMethods bootstrapMethods = classFile.getBootstrapMethods();<br style="font-size: 11px;"></div><div style="font-size: 11px;"><font color="#007fff" style="font-size: 11px;">//<b>即类加载就是将class文件转成Class对象,对标HotSpot中的Klass</b></font></div><div style="font-size: 11px;"><div style="font-size: 11px;">return new <b style="font-size: 11px;">Class</b>(classFile.accessFlags, name, superClassName, interfaceNames, methods, fields,&nbsp;<span style="background-color: initial; font-size: 11px;">bootstrapMethods, classFile.cpInfo, this, classFile);</span></div></div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;arcSize=3;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="1520" y="1200" width="360" height="320" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-11" value="Heap.registerClass(clazz.name, clazz);<br style="font-size: 11px;">String key = Utils.genNativeMethodKey(<br>method.clazz.name, method.name, method.descriptor);<br style="font-size: 11px;">NativeMethod nm = Heap.findMethod(key);<br><font color="#007fff">nm不存在打印异常信息</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="1001" y="1520" width="239" height="80" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-13" value="<font color="#007fff">就是遍历 clazz 中所有方法,寻找名为 main 的方法<br>注意这里 Class Method 对标HotSpot 中的Klass KMethod<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="730" y="1660" width="330" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-43" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-14" target="eWhodD4vRtD6RhS1Q6ua-42">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-14" value="<div style="font-size: 11px;"><font color="#007fff">//先创建一个方法栈帧</font></div><div style="font-size: 11px;">Frame frame = new <b>Frame</b>(method);</div><div style="font-size: 11px;"><font color="#007fff">//参数实例列表</font></div><div style="font-size: 11px;">Instance[] kargs = new <b>Instance</b>[args.length];</div><div style="font-size: 11px;">for (int i = 0; i &lt; args.length; i++) {</div><div style="font-size: 11px;">&nbsp; kargs[i] = Utils.str2Obj(args[i], frame.method.clazz.classLoader);</div><div style="font-size: 11px;">}</div><div style="font-size: 11px;"><font color="#007fff">//其实就是检查 java.lang.String 是否加载,未加载则执行加载并存到堆中</font></div><div style="font-size: 11px;">Class arrClazz = Heap.findClass("[Ljava/lang/String;");</div><div style="font-size: 11px;">if (arrClazz == null) {</div><div style="font-size: 11px;">&nbsp; arrClazz = new Class(1, "[Ljava/lang/String;", method.clazz.classLoader, null);</div><div style="font-size: 11px;">&nbsp; Heap.registerClass(arrClazz.name, arrClazz);</div><div style="font-size: 11px;">}</div><div style="font-size: 11px;"><font color="#007fff">//Instance[] -&gt; InstanceArray</font></div><div style="font-size: 11px;">InstanceArray array = new <b>InstanceArray</b>(arrClazz, kargs);</div><div style="font-size: 11px;"><font color="#007fff">//参数作为本地变量</font></div><div style="font-size: 11px;">frame.<b>setRef</b>(0, array);</div><div style="font-size: 11px;"><br style="font-size: 11px;"></div><div style="font-size: 11px;"><b>execute</b>(frame);</div>" style="rounded=1;whiteSpace=wrap;html=1;align=left;arcSize=3;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="760" y="1760" width="400" height="260" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-16" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Slot</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff"><b>变量槽</b>,表示某个变量或操作数,比如本地变量表就是一组变量槽</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//基本类型使用num存储,比如 int float long 'double 等</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//会转成 int 类型存储, 比如 int tmp = Float.floatToIntBits(val);</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//64位长的类型会转成两个int 使用两个 Slot 存储</font></p><p style="margin:0px;margin-left:4px;">public Integer <b>num</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//对象类型使用 ref 存储对象引用</font></p><p style="margin:0px;margin-left:4px;">public Instance <b>ref</b>;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1600" y="880" width="360" height="200" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-22" target="eWhodD4vRtD6RhS1Q6ua-27">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-22" value="Entry#<b>findClass</b>(String clazzName)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="1280" y="1100" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-30" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-27" target="eWhodD4vRtD6RhS1Q6ua-29">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-27" value="cf = <b>ClassReader</b>.<b>read</b>(path);<br><div><font color="#007fff">借助 DataInputStream 实现</font></div><div><font color="#007fff">按照 class 文件结构读取即可</font></div>" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1520" y="1100" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-58" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-29" target="eWhodD4vRtD6RhS1Q6ua-57">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-29" value="这里面包含对class文件各种结构的读取,包括 magic、主次版本号、常量池内容、类访问标志、超类、接口、字段、方法、属性等等" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1760" y="1100" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-31" value="<font color="#007fff">class文件中的属性用于保存比如源码文件名、<br>代码属性、异常处理表、行号表、局部变量表、常量表、<br>注解属性等</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1760" y="1040" width="320" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-32" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Attribute</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-740" y="1600" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-34" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-33" target="eWhodD4vRtD6RhS1Q6ua-32">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-33" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Code</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">代码属性</font></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;">public final int maxStacks;</p><p style="margin:0px;margin-left:4px;">public final int maxLocals;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//代码对应的字节码指令</font></p><p style="margin:0px;margin-left:4px;">public final Instruction[] <b>instructions</b>;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//异常处理表</font></p><p style="margin:0px;margin-left:4px;">public final ExceptionTable exceptionTable;</p><p style="margin:0px;margin-left:4px;">public final Attributes attributes;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-800" y="1720" width="360" height="200" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-37" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-36" target="eWhodD4vRtD6RhS1Q6ua-32">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-36" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ConstantValue</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">常量值</font></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;">public final Object val;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-1200" y="1720" width="360" height="100" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-38" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>Instruction (I)</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">字节码指令接口,每个字节码指令都有一个对应的实现</font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff"><br></font></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//指令偏移量,javap 反编译可以看到每个字节码指令前都有一个编号,这个编号是字节码指令在这个方法中的偏移量(各个指令偏移量累加的结果)</font></p><p style="margin:0px;margin-left:4px;">default int <b>offset</b>();<br></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;">void execute(Frame frame);</span><br></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;">default String format();<br></span></p><p style="margin:0px;margin-left:4px;"><span style="background-color: initial;"><br></span></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-800" y="1960" width="360" height="160" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-39" value="<font color="#007fff" style="font-size: 10px;">比如执行 Hello#main(String args) 方法创建的栈帧:<br style="font-size: 10px;"><div style="font-size: 10px;">public static void main(String[] args) {</div><div style="font-size: 10px;">&nbsp; &nbsp; System.out.println("hello");</div><div style="font-size: 10px;">}</div><div style="font-size: 10px;">对应的字节码:</div><div style="font-size: 10px;"><div style="font-size: 10px;">public static main([Ljava/lang/String;)V</div><div style="font-size: 10px;">&nbsp; &nbsp;L0</div><div style="font-size: 10px;">&nbsp; &nbsp; LINENUMBER 3 L0</div><div style="font-size: 10px;">&nbsp; &nbsp; <b>GETSTATIC</b> java/lang/System.out : Ljava/io/PrintStream;</div><div style="font-size: 10px;">&nbsp; &nbsp; <b>LDC</b> "hello"</div><div style="font-size: 10px;">&nbsp; &nbsp; <b>INVOKEVIRTUAL</b> java/io/PrintStream.println (Ljava/lang/String;)V</div><div style="font-size: 10px;">&nbsp; &nbsp;L1</div><div style="font-size: 10px;">&nbsp; &nbsp; LINENUMBER 4 L1</div><div style="font-size: 10px;">&nbsp; &nbsp; <b>RETURN</b></div><div style="font-size: 10px;">&nbsp; &nbsp;L2</div><div style="font-size: 10px;">&nbsp; &nbsp; LOCALVARIABLE args [Ljava/lang/String; L0 L2 0</div><div style="font-size: 10px;">&nbsp; &nbsp; MAXSTACK = 2</div><div style="font-size: 10px;">&nbsp; &nbsp; MAXLOCALS = 1</div></div><br style="font-size: 10px;"></font><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">frame = {Frame@1710}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">method</b> = {Method@1193}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">localVars</b> = {LocalVars@1717}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; slots = {Slot[1]@1748}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">operandStack</b> = {OperandStack@1720}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; slots = {Slot[2]@1749}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; top = 0</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">instructionMap</b> = {LinkedHashMap@1712}&nbsp; size = 4</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; {Integer@1734} 0 -&gt; {GetStaticInst@1735} "GetStaticInst{clazz='java/lang/System', fieldName='out', fieldDescriptor='Ljava/io/PrintStream;'}"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; {Integer@1736} 3 -&gt; {LdcInst@1737} "LdcInst{descriptor='Ljava/lang/String', val=hello}"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; {Integer@1738} 5 -&gt; {InvokeVirtualInst@1739} "InvokeVirtualInst{clazz='java/io/PrintStream', methodName='println', methodDescriptor='(Ljava/lang/String;)V'}"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; {Integer@1740} 8 -&gt; {ReturnInst@1741}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">thread</b> = {Thread@1723}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; top = 0</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; frames = {Frame[1024]@1753}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">nextPc</b> = 0</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">pc</b> = 0</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b style="font-size: 10px;">stat</b> = 0</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="760" y="2020" width="730" height="460" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-45" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-42" target="eWhodD4vRtD6RhS1Q6ua-44">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-42" value="Interpreter#<b>execute</b>(Frame newFrame)<br><font color="#007fff">解析器同步执行栈帧</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="1200" y="1860" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-47" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-44" target="eWhodD4vRtD6RhS1Q6ua-46">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-44" value="<div><font color="#007fff">//将main()栈帧压入main栈帧容器顶部</font></div><div>final Thread env = MetaSpace.getMainEnv();</div><div>env.pushFrame(newFrame);</div><div><br></div><div>newFrame.stat = Const.FAKE_FRAME;</div><div><font color="#007fff"><b>//从栈顶开始遍历方法所有字节码指令并执行</b></font></div><div>do {</div><div><font color="#007fff">&nbsp; //获取当前栈顶的栈帧</font></div><div>&nbsp; Frame frame = env.topFrame();</div><div><font color="#007fff">&nbsp; //pc = nextPc, 获取pc位置的字节码指令</font></div><div>&nbsp; Instruction instruction = frame.getInst();</div><div>&nbsp; frame.nextPc += instruction.offset();</div><div>&nbsp; traceBefore(instruction, frame); <font color="#007fff">//打印日志</font></div><div><font color="#007fff">&nbsp; //执行指令</font></div><div>&nbsp; instruction.<b>execute</b>(frame);&nbsp;</div><div>} while (newFrame.stat == Const.FAKE_FRAME);</div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;arcSize=2;" vertex="1" parent="1">
<mxGeometry x="1440" y="1770" width="320" height="240" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-49" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-46" target="eWhodD4vRtD6RhS1Q6ua-48">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-46" value="<b>GetStaticInst</b>#execute(Frame frame)<br><font color="#007fff">从类中获取静态字段压入操作数栈</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1800" y="1770" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-51" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-48" target="eWhodD4vRtD6RhS1Q6ua-50">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-65" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-48" target="eWhodD4vRtD6RhS1Q6ua-64">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-48" value="<b>LdcInst</b>#execute(Frame frame)<br><font color="#007fff">把常量池中的项压入操作数栈</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1800" y="1850" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-53" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-50" target="eWhodD4vRtD6RhS1Q6ua-52">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-71" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-50" target="eWhodD4vRtD6RhS1Q6ua-70">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-50" value="<b>InvokeVirtualInst</b>#execute(Frame frame)<br><font color="#007fff">按照对象的类来调用实例方法,这里即调用 println 方法</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1800" y="1945" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-52" value="<b>ReturnInst</b>#execute(Frame frame)<br><font color="#007fff">从方法中返回,返回值为void,这个指令内部主要就是将当前执行完的栈帧出栈</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1800" y="2030" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-57" value="代码属性的解析" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="2000" y="1100" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-61" target="eWhodD4vRtD6RhS1Q6ua-38">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-61" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>GetStaticInst</b><br></p><hr size="1"><p style="margin:0px;margin-left:4px;"><font color="#007fff">从类中获取静态字段指令</font></p><p style="margin:0px;margin-left:4px;"><br></p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//从哪个类中获取</font></p><p style="margin:0px;margin-left:4px;">public final String clazz;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//获取字段名</font></p><p style="margin:0px;margin-left:4px;">public final String fieldName;</p><p style="margin:0px;margin-left:4px;"><font color="#007fff">//字段返回类型</font></p><p style="margin:0px;margin-left:4px;">public final String fieldDescriptor;</p><hr size="1"><p style="margin:0px;margin-left:4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="-800" y="2160" width="360" height="160" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-62" value="0" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2280" y="1780" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-63" value="num = null<br>ref = System.out 实例引用" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="2320" y="1780" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-64" value="...<br>Interpreter.execute(klass.getMethod("&lt;clinit&gt;", "()V"));<br>...<br><font style="font-size: 10px;" color="#007fff">首次这里还会执行静态初始化方法,因为String 中有静态成员赋值操作</font>" style="rounded=1;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="2040" y="1840" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-66" value="1" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2280" y="1840" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-67" value="num = null<br>ref = "Hello"的String实例引用" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="2320" y="1840" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-68" value="0" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2280" y="1880" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-69" value="num = null<br>ref = System.out 实例引用" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="2320" y="1880" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-72" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="eWhodD4vRtD6RhS1Q6ua-70" target="eWhodD4vRtD6RhS1Q6ua-44">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2260" y="1975" />
<mxPoint x="2260" y="1740" />
<mxPoint x="1420" y="1740" />
<mxPoint x="1420" y="1830" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-70" value="调用实例方法(如PrintStream.println() )<b>会创建新的栈帧</b>,将上一个栈帧的操作数栈pop压入新栈帧的本地变量表,然后新栈帧压入main栈顶,并更新相关参数,然后<b>回到前面的while循环会执行新的栈帧的指令</b>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="2040" y="1930" width="200" height="90" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-73" value="<font color="#007fff">println() 方法被编译为18个字节码指令<br>里面还有好几层方法调用<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2280" y="1940" width="220" height="40" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-75" value="<font color="#007fff">操作数栈</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2355" y="1740" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="eWhodD4vRtD6RhS1Q6ua-83" value="<div><font color="#007fff">Compiled from "Hello.java"</font></div><div><font color="#007fff">public class Hello {</font></div><div><font color="#007fff">&nbsp; public Hello();</font></div><div><font color="#007fff">&nbsp; &nbsp; Code:</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;0: aload_0</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;1: invokespecial #1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Method java/lang/Object."&lt;init&gt;":()V</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;4: return</font></div><div><font color="#007fff"><br></font></div><div><font color="#007fff">&nbsp; public static void main(java.lang.String[]);</font></div><div><font color="#007fff">&nbsp; &nbsp; Code:</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;<b>0</b>: getstatic&nbsp; &nbsp; &nbsp;#2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Field java/lang/System.out:Ljava/io/PrintStream;</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;3: ldc&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // String hello</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;5: invokevirtual #4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Method java/io/PrintStream.println:(Ljava/lang/String;)V</font></div><div><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp;8: return</font></div><div><font color="#007fff">}</font></div><div><br></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="-1320" y="1960" width="510" height="240" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>