-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconcept.txt
156 lines (123 loc) · 4.18 KB
/
concept.txt
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
next frame with exception handler instead of != null?
localThread needed?
----
call -> normal
restore method handle
restore code only for interrupts
what about restore code for run()? helper method calls real run()?
generate method handles
remember method handles during serialize
private void dynamicXXX(ClassNode clazz) {
for (MethodNode method : clazz.methods) {
AbstractInsnNode[] instructions = method.instructions.toArray();
for (AbstractInsnNode instruction : instructions) {
if (instruction instanceof InvokeDynamicInsnNode dynamic) {
System.err.println(">>> " + methodName(clazz, method) + ": " + dynamic.bsm + " [" + dynamic.bsmArgs.length + "]");
// dynamic.desc = changeDescXXX(dynamic.desc);
for (int i = 0; i < dynamic.bsmArgs.length; i++) {
Object bsmArg = dynamic.bsmArgs[i];
System.err.println(">>>- " + bsmArg);
}
for (int i = 0; i < dynamic.bsmArgs.length; i++) {
Object bsmArg = dynamic.bsmArgs[i];
if (bsmArg instanceof Handle handle) {
if (classInfoCache.isInterruptible(handle)) {
String desc = changeDescXXX(handle.getDesc());
dynamic.bsmArgs[i - 1] = Type.getType(desc);
dynamic.bsmArgs[i] = new Handle(handle.getTag(), handle.getOwner(), handle.getName(), desc);
dynamic.bsmArgs[i + 1] = Type.getType(desc);
}
}
}
for (int i = 0; i < dynamic.bsmArgs.length; i++) {
Object bsmArg = dynamic.bsmArgs[i];
System.err.println(">>>+ " + bsmArg);
}
}
}
}
}
protected String changeDescXXX(String desc) {
int index = desc.indexOf(")");
return desc.substring(0, index) + THREAD_IMPL_DESC + FRAME_IMPL_DESC + desc.substring(index);
}
test
-------------------------------------------------------------------------------
SFE new:
--------
run:
- restore code dispatcher just for run
- not run: store last frame in local, call method handle of last frame
- while not serializing: local last frame--, call method handle of last frame
copy:
- restore code dispatcher which just restores the frame and jumps after interrupt/method call
- static field with same name with (unbound) method handle
interrupt:
- set last frame
method:
- same as frequent3
-------------------------------------------------------------------------------
SFE:
----
run:
- normal start vs.
- method handle call of last interrupt
- returned: new call, if no capture
- capture code
- replace returns with exception
abstract:
- signature + thread & (previous) frame
abstract copy:
- signature + thread & (previous) frame, no return value, private
concrete:
- signature + thread & (previous) frame
- init code, calculate current frame
- no restore code
- interrupt, capture top most frame
- capture code
concrete copy:
- signature == thread & (previous) frame, no return value
- init code, calculate current frame
- restore code only for interrupt
- interrupt, capture top most frame
- capture code: end of capture (because directly called by run())
- capture return value into frame at original exit points
-------------------------------------------------------------------------------
Ideas:
------
@RestorePoint?
-------------------------------------------------------------------------------
entered method / no capture:
remember level in local
level++
normal
entered method / capture:
remember level in local
level++
dispatcher
dummy args
enter interrupted method (direct call) | avoids restore of complete stack
jump after normal method call (to "leave method" code) |
PROBLEM: stack mismatch: special restore code or restore frame before method call
interrupt:
capture frame
set level to have being captured
set capture
interrupt end:
reset capture
set level to have not being captured
restore frame
left method / no capture:
level--,
set level to have not being captured
restore frame
left method / capture:
level--
if level not captured
capture frame
set level to have being captured
return
catch block:
reset context to remembered level
restore frame
normal