Skip to content

Commit 07d2667

Browse files
committed
Add more samples
1 parent 35ffdff commit 07d2667

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

content/posts/notes_on_jvm_anatomy.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,161 @@ public class com/slateblua/bytecode/MyClass {
154154
}
155155
```
156156

157+
For a more "complex" example, let's create a toy-class InMemoryDataSource that extends AbstractDataSource
158+
and implements the LocalDataSource interface.
159+
160+
```java
161+
package com.slateblua.bytecode;
162+
163+
import java.util.List;
164+
165+
public class InMemoryDataSource extends AbstractDataSource implements LocalDataSource {
166+
static {
167+
System.out.println("In-memory data source first accessed");
168+
}
169+
170+
@Override
171+
public List<String> getAllRecords () {
172+
return List.of("Record", "Another record");
173+
}
174+
175+
@Override
176+
public String getRecordById (int key) {
177+
return "Record " + key;
178+
}
179+
180+
@Override
181+
public void addRecord (String record) {
182+
System.out.println("Record added: " + record);
183+
}
184+
185+
@Override
186+
public void deleteRecord (int key) {
187+
System.out.println("Record deleted: " + key);
188+
}
189+
}
190+
```
191+
192+
The following bytecode is generated for the InMemoryDataSource class:
193+
194+
```java
195+
// class version 62.0 (62)
196+
// access flags 0x21
197+
public class com/slateblua/bytecode/InMemoryDataSource extends com/slateblua/bytecode/AbstractDataSource implements com/slateblua/bytecode/LocalDataSource {
198+
199+
// compiled from: InMemoryDataSource.java
200+
// access flags 0x19
201+
public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
202+
203+
// access flags 0x1
204+
public <init>()V
205+
L0
206+
LINENUMBER 5 L0
207+
ALOAD 0
208+
INVOKESPECIAL com/slateblua/bytecode/AbstractDataSource.<init> ()V
209+
RETURN
210+
L1
211+
LOCALVARIABLE this Lcom/slateblua/bytecode/InMemoryDataSource; L0 L1 0
212+
MAXSTACK = 1
213+
MAXLOCALS = 1
214+
215+
// access flags 0x1
216+
// signature ()Ljava/util/List<Ljava/lang/String;>;
217+
// declaration: java.util.List<java.lang.String> getAllRecords()
218+
public getAllRecords()Ljava/util/List;
219+
L0
220+
LINENUMBER 12 L0
221+
LDC "Record"
222+
LDC "Another record"
223+
INVOKESTATIC java/util/List.of (Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List; (itf)
224+
ARETURN
225+
L1
226+
LOCALVARIABLE this Lcom/slateblua/bytecode/InMemoryDataSource; L0 L1 0
227+
MAXSTACK = 2
228+
MAXLOCALS = 1
229+
230+
// access flags 0x1
231+
public getRecordById(I)Ljava/lang/String;
232+
L0
233+
LINENUMBER 17 L0
234+
ILOAD 1
235+
INVOKEDYNAMIC makeConcatWithConstants(I)Ljava/lang/String; [
236+
// handle kind 0x6 : INVOKESTATIC
237+
java/lang/invoke/StringConcatFactory.makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
238+
// arguments:
239+
"Record \u0001"
240+
]
241+
ARETURN
242+
L1
243+
LOCALVARIABLE this Lcom/slateblua/bytecode/InMemoryDataSource; L0 L1 0
244+
LOCALVARIABLE key I L0 L1 1
245+
MAXSTACK = 1
246+
MAXLOCALS = 2
247+
248+
// access flags 0x1
249+
public addRecord(Ljava/lang/String;)V
250+
L0
251+
LINENUMBER 22 L0
252+
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
253+
ALOAD 1
254+
INVOKEDYNAMIC makeConcatWithConstants(Ljava/lang/String;)Ljava/lang/String; [
255+
// handle kind 0x6 : INVOKESTATIC
256+
java/lang/invoke/StringConcatFactory.makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
257+
// arguments:
258+
"Record added: \u0001"
259+
]
260+
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
261+
L1
262+
LINENUMBER 23 L1
263+
RETURN
264+
L2
265+
LOCALVARIABLE this Lcom/slateblua/bytecode/InMemoryDataSource; L0 L2 0
266+
LOCALVARIABLE record Ljava/lang/String; L0 L2 1
267+
MAXSTACK = 2
268+
MAXLOCALS = 2
269+
270+
// access flags 0x1
271+
public deleteRecord(I)V
272+
L0
273+
LINENUMBER 27 L0
274+
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
275+
ILOAD 1
276+
INVOKEDYNAMIC makeConcatWithConstants(I)Ljava/lang/String; [
277+
// handle kind 0x6 : INVOKESTATIC
278+
java/lang/invoke/StringConcatFactory.makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
279+
// arguments:
280+
"Record deleted: \u0001"
281+
]
282+
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
283+
L1
284+
LINENUMBER 28 L1
285+
RETURN
286+
L2
287+
LOCALVARIABLE this Lcom/slateblua/bytecode/InMemoryDataSource; L0 L2 0
288+
LOCALVARIABLE key I L0 L2 1
289+
MAXSTACK = 2
290+
MAXLOCALS = 2
291+
292+
// access flags 0x8
293+
static <clinit>()V
294+
L0
295+
LINENUMBER 7 L0
296+
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
297+
LDC "In-memory data source first accessed"
298+
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
299+
L1
300+
LINENUMBER 8 L1
301+
RETURN
302+
MAXSTACK = 2
303+
MAXLOCALS = 0
304+
}
305+
```
306+
307+
The <clinit> (the static initializer) method is called only once for a class.
308+
It is called before any other method of the class can be executed.
309+
310+
In contrast, the <init> method is called for every object creation. Here it initializes the <init> method of the super class and the references to the current object.
311+
157312
### Execution engine: interpreters, JIT, AOT
158313
159314
JVM may execute bytecode via

0 commit comments

Comments
 (0)