-
Notifications
You must be signed in to change notification settings - Fork 0
/
luajit-openresty-features.patch
824 lines (765 loc) · 24.2 KB
/
luajit-openresty-features.patch
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
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
From a6879cb3982f02744dd77b6663ae6bc14162e652 Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
Date: Sat, 19 Dec 2015 10:43:32 -0800
Subject: [PATCH 02/13] Makefile: ensure we always install the symlink for
"luajit".
---
Makefile | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
index 923bf72b..f4b84081 100644
--- a/Makefile
+++ b/Makefile
@@ -130,13 +130,8 @@ install: $(LUAJIT_BIN)
$(RM) $(FILE_PC).tmp
cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC)
cd src/jit && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
+ $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)
@echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ===="
- @echo ""
- @echo "Note: the development releases deliberately do NOT install a symlink for luajit"
- @echo "You can do this now by running this command (with sudo):"
- @echo ""
- @echo " $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)"
- @echo ""
uninstall:
--
2.21.0
From e29e78dd64573947777e8ca7741d46d1c0ba2f7b Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
Date: Tue, 14 Mar 2017 14:26:48 -0700
Subject: [PATCH 03/13] optimize: lj_str_new: tests the full hash value before
doing the full string comparison on hash collisions. thanks Shuxin Yang for
the patch.
---
src/lj_str.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lj_str.c b/src/lj_str.c
index 264dedc1..f1b5fb5d 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -152,7 +152,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
while (o != NULL) {
GCstr *sx = gco2str(o);
- if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
+ if (sx->len == len && sx->hash == h && str_fastcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
@@ -162,7 +162,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
} else { /* Slow path: end of string is too close to a page boundary. */
while (o != NULL) {
GCstr *sx = gco2str(o);
- if (sx->len == len && memcmp(str, strdata(sx), len) == 0) {
+ if (sx->len == len && sx->hash == h && memcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
--
2.21.0
From 555ee4e814f799937ca505423fc05c0b0402f81c Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <yichun@openresty.com>
Date: Tue, 15 Jan 2019 12:17:50 -0800
Subject: [PATCH 04/13] bugfix: fixed assertion failure "lj_record.c:92:
rec_check_slots: Assertion `nslots <= 250' failed" found by stressing our
edgelang compiler.
---
src/lj_record.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/lj_record.c b/src/lj_record.c
index 7f37d6c6..4a50de1b 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1860,6 +1860,8 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
lj_trace_err_info(J, LJ_TRERR_NYIBC);
}
}
+ if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
+ lj_trace_err(J, LJ_TRERR_STACKOV);
}
/* -- Record allocations -------------------------------------------------- */
--
2.21.0
From 58e9941b6268202f7953a5534e0c662ad90b2510 Mon Sep 17 00:00:00 2001
From: doujiang24 <doujiang24@gmail.com>
Date: Sun, 12 Mar 2017 21:04:50 +0800
Subject: [PATCH 05/13] feature: added the bytecode option `L` to display lua
source line numbers.
Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
---
src/jit/bc.lua | 20 +++++++++++++-------
src/jit/bcsave.lua | 11 ++++++++---
src/lib_jit.c | 6 ++++++
3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/jit/bc.lua b/src/jit/bc.lua
index 193cf01f..80f92689 100644
--- a/src/jit/bc.lua
+++ b/src/jit/bc.lua
@@ -63,15 +63,21 @@ local function ctlsub(c)
end
-- Return one bytecode line.
-local function bcline(func, pc, prefix)
- local ins, m = funcbc(func, pc)
+local function bcline(func, pc, prefix, lineinfo)
+ local ins, m, l = funcbc(func, pc, lineinfo and 1 or 0)
if not ins then return end
local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128)
local a = band(shr(ins, 8), 0xff)
local oidx = 6*band(ins, 0xff)
local op = sub(bcnames, oidx+1, oidx+6)
- local s = format("%04d %s %-6s %3s ",
- pc, prefix or " ", op, ma == 0 and "" or a)
+ local s
+ if lineinfo then
+ s = format("%04d %7s %s %-6s %3s ",
+ pc, "["..l.."]", prefix or " ", op, ma == 0 and "" or a)
+ else
+ s = format("%04d %s %-6s %3s ",
+ pc, prefix or " ", op, ma == 0 and "" or a)
+ end
local d = shr(ins, 16)
if mc == 13*128 then -- BCMjump
return format("%s=> %04d\n", s, pc+d-0x7fff)
@@ -124,20 +130,20 @@ local function bctargets(func)
end
-- Dump bytecode instructions of a function.
-local function bcdump(func, out, all)
+local function bcdump(func, out, all, lineinfo)
if not out then out = stdout end
local fi = funcinfo(func)
if all and fi.children then
for n=-1,-1000000000,-1 do
local k = funck(func, n)
if not k then break end
- if type(k) == "proto" then bcdump(k, out, true) end
+ if type(k) == "proto" then bcdump(k, out, true, lineinfo) end
end
end
out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
local target = bctargets(func)
for pc=1,1000000000 do
- local s = bcline(func, pc, target[pc] and "=>")
+ local s = bcline(func, pc, target[pc] and "=>", lineinfo)
if not s then break end
out:write(s)
end
diff --git a/src/jit/bcsave.lua b/src/jit/bcsave.lua
index 2553d97e..9c6146c2 100644
--- a/src/jit/bcsave.lua
+++ b/src/jit/bcsave.lua
@@ -23,6 +23,7 @@ local function usage()
io.stderr:write[[
Save LuaJIT bytecode: luajit -b[options] input output
-l Only list bytecode.
+ -L Only list bytecode with lineinfo.
-s Strip debug info (default).
-g Keep debug info.
-n name Set module name (default: auto-detect from input name).
@@ -575,9 +576,9 @@ end
------------------------------------------------------------------------------
-local function bclist(input, output)
+local function bclist(input, output, lineinfo)
local f = readfile(input)
- require("jit.bc").dump(f, savefile(output, "w"), true)
+ require("jit.bc").dump(f, savefile(output, "w"), true, lineinfo)
end
local function bcsave(ctx, input, output)
@@ -604,6 +605,7 @@ local function docmd(...)
local arg = {...}
local n = 1
local list = false
+ local lineinfo = false
local ctx = {
strip = true, arch = jit.arch, os = string.lower(jit.os),
type = false, modname = false,
@@ -617,6 +619,9 @@ local function docmd(...)
local opt = string.sub(a, m, m)
if opt == "l" then
list = true
+ elseif opt == "L" then
+ list = true
+ lineinfo = true
elseif opt == "s" then
ctx.strip = true
elseif opt == "g" then
@@ -645,7 +650,7 @@ local function docmd(...)
end
if list then
if #arg == 0 or #arg > 2 then usage() end
- bclist(arg[1], arg[2] or "-")
+ bclist(arg[1], arg[2] or "-", lineinfo)
else
if #arg ~= 2 then usage() end
bcsave(ctx, arg[1], arg[2])
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 6e265fdb..6972550b 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -224,6 +224,7 @@ LJLIB_CF(jit_util_funcbc)
{
GCproto *pt = check_Lproto(L, 0);
BCPos pc = (BCPos)lj_lib_checkint(L, 2);
+ int lineinfo = lj_lib_optint(L, 3, 0);
if (pc < pt->sizebc) {
BCIns ins = proto_bc(pt)[pc];
BCOp op = bc_op(ins);
@@ -231,6 +232,11 @@ LJLIB_CF(jit_util_funcbc)
setintV(L->top, ins);
setintV(L->top+1, lj_bc_mode[op]);
L->top += 2;
+ if (lineinfo) {
+ setintV(L->top, lj_debug_line(pt, pc));
+ L->top += 1;
+ return 3;
+ }
return 2;
}
return 0;
--
2.21.0
From a61c93d0784c532db4ec0797475a0e0ad93dda4c Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <yichun@openresty.com>
Date: Wed, 27 Feb 2019 17:20:19 -0800
Subject: [PATCH 06/13] bugfix: ffi.C.FUNC(): it lacked a write barrier which
might lead to use-after-free issues and memory corruptions.
Fix #42.
---
src/lj_clib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lj_clib.c b/src/lj_clib.c
index f016b06b..a8672052 100644
--- a/src/lj_clib.c
+++ b/src/lj_clib.c
@@ -384,6 +384,7 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
cd = lj_cdata_new(cts, id, CTSIZE_PTR);
*(void **)cdataptr(cd) = p;
setcdataV(L, tv, cd);
+ lj_gc_anybarriert(L, cl->cache);
}
}
return tv;
--
2.21.0
From 3086b483e76ad12ae0a0dfab60960c1175b69dab Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
Date: Thu, 15 May 2014 16:03:29 -0700
Subject: [PATCH 07/13] feature: added internal memory-buffer-based trace
entry/exit/start-recording event logging, mainly for debugging bugs in the
JIT compiler. it requires -DLUA_USE_TRACE_LOGS when building.
---
src/lj_debug.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
src/lj_debug.h | 11 +++++
src/lj_trace.c | 9 ++++
src/vm_x86.dasc | 24 ++++++++++
4 files changed, 169 insertions(+)
diff --git a/src/lj_debug.c b/src/lj_debug.c
index 959dc289..7f4f793a 100644
--- a/src/lj_debug.c
+++ b/src/lj_debug.c
@@ -697,3 +697,128 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
lua_concat(L, (int)(L->top - L->base) - top);
}
+#ifdef LUA_USE_TRACE_LOGS
+
+#include "lj_dispatch.h"
+
+#define MAX_TRACE_EVENTS 64
+
+enum {
+ LJ_TRACE_EVENT_ENTER,
+ LJ_TRACE_EVENT_EXIT,
+ LJ_TRACE_EVENT_START
+};
+
+typedef struct {
+ int event;
+ unsigned traceno;
+ unsigned exitno;
+ int directexit;
+ const BCIns *ins;
+ lua_State *thread;
+ GCfunc *fn;
+} lj_trace_event_record_t;
+
+static lj_trace_event_record_t lj_trace_events[MAX_TRACE_EVENTS];
+
+static int rb_start = 0;
+static int rb_end = 0;
+static int rb_full = 0;
+
+static void
+lj_trace_log_event(lj_trace_event_record_t *rec)
+{
+ lj_trace_events[rb_end] = *rec;
+
+ if (rb_full) {
+ rb_end++;
+ if (rb_end == MAX_TRACE_EVENTS) {
+ rb_end = 0;
+ }
+ rb_start = rb_end;
+
+ } else {
+ rb_end++;
+ if (rb_end == MAX_TRACE_EVENTS) {
+ rb_end = 0;
+ rb_full = MAX_TRACE_EVENTS;
+ }
+ }
+}
+
+static GCfunc*
+lj_debug_top_frame_fn(lua_State *L, const BCIns *pc)
+{
+ int size;
+ cTValue *frame;
+
+ frame = lj_debug_frame(L, 0, &size);
+ if (frame == NULL) {
+ return NULL;
+ }
+
+ return frame_func(frame);
+}
+
+void
+lj_log_trace_start_record(lua_State *L, unsigned traceno, const BCIns *pc,
+ GCfunc *fn)
+{
+ lj_trace_event_record_t r;
+
+ r.event = LJ_TRACE_EVENT_START;
+ r.thread = L;
+ r.ins = pc;
+ r.traceno = traceno;
+ r.fn = fn;
+
+ lj_trace_log_event(&r);
+}
+
+void
+lj_log_trace_entry(lua_State *L, unsigned traceno, const BCIns *pc)
+{
+ lj_trace_event_record_t r;
+
+ r.event = LJ_TRACE_EVENT_ENTER;
+ r.thread = L;
+ r.ins = pc;
+ r.traceno = traceno;
+ r.fn = lj_debug_top_frame_fn(L, pc);
+
+ lj_trace_log_event(&r);
+}
+
+static void
+lj_log_trace_exit_helper(lua_State *L, int vmstate, const BCIns *pc, int direct)
+{
+ if (vmstate >= 0) {
+ lj_trace_event_record_t r;
+
+ jit_State *J = L2J(L);
+
+ r.event = LJ_TRACE_EVENT_EXIT;
+ r.thread = L;
+ r.ins = pc;
+ r.traceno = vmstate;
+ r.exitno = J->exitno;
+ r.directexit = direct;
+ r.fn = lj_debug_top_frame_fn(L, pc);
+
+ lj_trace_log_event(&r);
+ }
+}
+
+void
+lj_log_trace_normal_exit(lua_State *L, int vmstate, const BCIns *pc)
+{
+ lj_log_trace_exit_helper(L, vmstate, pc, 0);
+}
+
+void
+lj_log_trace_direct_exit(lua_State *L, int vmstate, const BCIns *pc)
+{
+ lj_log_trace_exit_helper(L, vmstate, pc, 1);
+}
+
+#endif /* LUA_USE_TRACE_LOGS */
diff --git a/src/lj_debug.h b/src/lj_debug.h
index 5917c00b..82f53bda 100644
--- a/src/lj_debug.h
+++ b/src/lj_debug.h
@@ -62,4 +62,15 @@ enum {
VARNAME__MAX
};
+#ifdef LUA_USE_TRACE_LOGS
+LJ_FUNC void LJ_FASTCALL lj_log_trace_direct_exit(lua_State *L,
+ int vmstate, const BCIns *pc);
+LJ_FUNC void LJ_FASTCALL lj_log_trace_normal_exit(lua_State *L,
+ int vmstate, const BCIns *pc);
+LJ_FUNC void LJ_FASTCALL lj_log_trace_entry(lua_State *L,
+ unsigned traceno, const BCIns *pc);
+LJ_FUNC void LJ_FASTCALL lj_log_trace_start_record(lua_State *L, unsigned traceno,
+ const BCIns *pc, GCfunc *fn);
+#endif
+
#endif
diff --git a/src/lj_trace.c b/src/lj_trace.c
index d85b47f8..c2f0d8cf 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -404,6 +404,9 @@ static void trace_start(jit_State *J)
{
lua_State *L;
TraceNo traceno;
+#ifdef LUA_USE_TRACE_LOGS
+ const BCIns *pc = J->pc;
+#endif
if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
if (J->parent == 0 && J->exitno == 0) {
@@ -462,6 +465,9 @@ static void trace_start(jit_State *J)
}
);
lj_record_setup(J);
+#ifdef LUA_USE_TRACE_LOGS
+ lj_log_trace_start_record(L, (unsigned) J->cur.traceno, pc, J->fn);
+#endif
}
/* Stop tracing. */
@@ -890,6 +896,9 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
}
}
}
+#ifdef LUA_USE_TRACE_LOGS
+ lj_log_trace_normal_exit(L, (int) T->traceno, pc);
+#endif
/* Return MULTRES or 0. */
ERRNO_RESTORE
switch (bc_op(*pc)) {
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 211ae7b9..66377cd5 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -2919,6 +2919,19 @@ static void build_subroutines(BuildCtx *ctx)
| mov r13, TMPa
| mov r12, TMPQ
|.endif
+#ifdef LUA_USE_TRACE_LOGS
+ | mov FCARG1, SAVE_L
+ | mov L:FCARG1->base, BASE
+ | mov RB, RD // Save RD
+ | mov TMP1, PC // Save PC
+ | mov CARG3d, PC // CARG3d == BASE
+ | mov FCARG2, dword [DISPATCH+DISPATCH_GL(vmstate)]
+ | call extern lj_log_trace_direct_exit@8
+ | mov PC, TMP1
+ | mov RD, RB
+ | mov RB, SAVE_L
+ | mov BASE, L:RB->base
+#endif
| test RD, RD; js >9 // Check for error from exit.
| mov L:RB, SAVE_L
| mov MULTRES, RD
@@ -5260,6 +5273,17 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
case BC_JLOOP:
|.if JIT
| ins_AD // RA = base (ignored), RD = traceno
+#ifdef LUA_USE_TRACE_LOGS
+ | mov L:RB, SAVE_L
+ | mov L:RB->base, BASE // Save BASE
+ | mov TMP1, RD // Save RD
+ | mov CARG3d, PC // CARG3d == BASE
+ | mov FCARG2, RD
+ | mov FCARG1, RB
+ | call extern lj_log_trace_entry@8
+ | mov RD, TMP1
+ | mov BASE, L:RB->base
+#endif
| mov RA, [DISPATCH+DISPATCH_J(trace)]
| mov TRACE:RD, [RA+RD*4]
| mov RDa, TRACE:RD->mcode
--
2.21.0
From 00a5957d632f1715fdc88c1a3fe7cc355f5a13cb Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
Date: Wed, 21 May 2014 16:05:13 -0700
Subject: [PATCH 08/13] bugfix: fixed build regression on i386 introduced by
the LUA_USE_TRACE_LOGS feature.
---
src/vm_x86.dasc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 66377cd5..50210010 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -2920,6 +2920,7 @@ static void build_subroutines(BuildCtx *ctx)
| mov r12, TMPQ
|.endif
#ifdef LUA_USE_TRACE_LOGS
+ |.if X64
| mov FCARG1, SAVE_L
| mov L:FCARG1->base, BASE
| mov RB, RD // Save RD
@@ -2931,6 +2932,7 @@ static void build_subroutines(BuildCtx *ctx)
| mov RD, RB
| mov RB, SAVE_L
| mov BASE, L:RB->base
+ |.endif
#endif
| test RD, RD; js >9 // Check for error from exit.
| mov L:RB, SAVE_L
@@ -5274,6 +5276,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|.if JIT
| ins_AD // RA = base (ignored), RD = traceno
#ifdef LUA_USE_TRACE_LOGS
+ |.if X64
| mov L:RB, SAVE_L
| mov L:RB->base, BASE // Save BASE
| mov TMP1, RD // Save RD
@@ -5283,6 +5286,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| call extern lj_log_trace_entry@8
| mov RD, TMP1
| mov BASE, L:RB->base
+ |.endif
#endif
| mov RA, [DISPATCH+DISPATCH_J(trace)]
| mov TRACE:RD, [RA+RD*4]
--
2.21.0
From 7950afe36eadad8b529f4aa90b303861619a2322 Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
Date: Sat, 7 Jun 2014 13:41:24 -0700
Subject: [PATCH 09/13] fixed compilation errors on Solaris when
-DLUA_USE_TRACE_LOGS is enabled.
---
src/lj_debug.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/lj_debug.c b/src/lj_debug.c
index 7f4f793a..b93b69d3 100644
--- a/src/lj_debug.c
+++ b/src/lj_debug.c
@@ -760,7 +760,7 @@ lj_debug_top_frame_fn(lua_State *L, const BCIns *pc)
return frame_func(frame);
}
-void
+LJ_FUNC void LJ_FASTCALL
lj_log_trace_start_record(lua_State *L, unsigned traceno, const BCIns *pc,
GCfunc *fn)
{
@@ -775,7 +775,7 @@ lj_log_trace_start_record(lua_State *L, unsigned traceno, const BCIns *pc,
lj_trace_log_event(&r);
}
-void
+LJ_FUNC void LJ_FASTCALL
lj_log_trace_entry(lua_State *L, unsigned traceno, const BCIns *pc)
{
lj_trace_event_record_t r;
@@ -809,13 +809,13 @@ lj_log_trace_exit_helper(lua_State *L, int vmstate, const BCIns *pc, int direct)
}
}
-void
+LJ_FUNC void LJ_FASTCALL
lj_log_trace_normal_exit(lua_State *L, int vmstate, const BCIns *pc)
{
lj_log_trace_exit_helper(L, vmstate, pc, 0);
}
-void
+LJ_FUNC void LJ_FASTCALL
lj_log_trace_direct_exit(lua_State *L, int vmstate, const BCIns *pc)
{
lj_log_trace_exit_helper(L, vmstate, pc, 1);
--
2.21.0
From bd304a366be2ffb10eec6aeba390595232958320 Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <agentzh@gmail.com>
Date: Tue, 27 May 2014 12:37:13 -0700
Subject: [PATCH 10/13] feature: jit.dump: output Lua source location after
every BC.
---
src/jit/dump.lua | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/jit/dump.lua b/src/jit/dump.lua
index 2bea652b..ef0dca61 100644
--- a/src/jit/dump.lua
+++ b/src/jit/dump.lua
@@ -591,6 +591,9 @@ local function dump_record(tr, func, pc, depth, callee)
if pc >= 0 then
line = bcline(func, pc, recprefix)
if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
+ if pc > 0 then
+ line = sub(line, 1, -2) .. " (" .. fmtfunc(func, pc) .. ")\n"
+ end
else
line = "0000 "..recprefix.." FUNCC \n"
callee = func
--
2.21.0
From cce112ca4fdde7d1ca5963c50d0621fb2e526524 Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <yichun@openresty.com>
Date: Fri, 5 Apr 2019 12:38:40 -0700
Subject: [PATCH 11/13] feature: luajit -bl: dump the constant tables (KGC and
KN) for each lua proto object as well.
---
src/jit/bc.lua | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/jit/bc.lua b/src/jit/bc.lua
index 80f92689..9fee4cda 100644
--- a/src/jit/bc.lua
+++ b/src/jit/bc.lua
@@ -141,6 +141,38 @@ local function bcdump(func, out, all, lineinfo)
end
end
out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
+
+ for n=-1,-1000000000,-1 do
+ local kc = funck(func, n)
+ if not kc then break end
+
+ local typ = type(kc)
+ if typ == "string" then
+ kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub))
+ out:write(format("KGC %d %s\n", -(n + 1), kc))
+ elseif typ == "proto" then
+ local fi = funcinfo(kc)
+ if fi.ffid then
+ kc = vmdef.ffnames[fi.ffid]
+ else
+ kc = fi.loc
+ end
+ out:write(format("KGC %d %s\n", -(n + 1), kc))
+ elseif typ == "table" then
+ out:write(format("KGC %d table\n", -(n + 1)))
+ else
+ -- error("unknown KGC type: " .. typ)
+ end
+ end
+
+ for n=1,1000000000 do
+ local kc = funck(func, n)
+ if not kc then break end
+ if type(kc) == "number" then
+ out:write(format("KN %d %s\n", n, kc))
+ end
+ end
+
local target = bctargets(func)
for pc=1,1000000000 do
local s = bcline(func, pc, target[pc] and "=>", lineinfo)
--
2.21.0
From 7d5f5be581ed392059601168a95068e026765aa0 Mon Sep 17 00:00:00 2001
From: "Yichun Zhang (agentzh)" <yichun@openresty.com>
Date: Fri, 17 May 2019 14:49:48 -0700
Subject: [PATCH 13/13] bugfix: thanks Julien Desgats for the report and Peter
Cawley for the patch.
The test covering this bug was submitted to the openresty/luajit2-test-suite
repo as commit ce2c916d55.
---
src/lj_tab.c | 81 ++++++++++++++++++++++++++++++++++------------------
1 file changed, 53 insertions(+), 28 deletions(-)
diff --git a/src/lj_tab.c b/src/lj_tab.c
index c51666d3..ff216f3c 100644
--- a/src/lj_tab.c
+++ b/src/lj_tab.c
@@ -474,6 +474,7 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
lua_assert(freenode != &G(L)->nilnode);
collide = hashkey(t, &n->key);
if (collide != n) { /* Colliding node not the main node? */
+ Node *nn;
while (noderef(collide->next) != n) /* Find predecessor. */
collide = nextnode(collide);
setmref(collide->next, freenode); /* Relink chain. */
@@ -483,39 +484,63 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
freenode->next = n->next;
setmref(n->next, NULL);
setnilV(&n->val);
- /* Rechain pseudo-resurrected string keys with colliding hashes. */
- while (nextnode(freenode)) {
- Node *nn = nextnode(freenode);
- if (tvisstr(&nn->key) && !tvisnil(&nn->val) &&
- hashstr(t, strV(&nn->key)) == n) {
- freenode->next = nn->next;
- nn->next = n->next;
- setmref(n->next, nn);
- /*
- ** Rechaining a resurrected string key creates a new dilemma:
- ** Another string key may have originally been resurrected via
- ** _any_ of the previous nodes as a chain anchor. Including
- ** a node that had to be moved, which makes them unreachable.
- ** It's not feasible to check for all previous nodes, so rechain
- ** any string key that's currently in a non-main positions.
- */
- while ((nn = nextnode(freenode))) {
- if (tvisstr(&nn->key) && !tvisnil(&nn->val)) {
- Node *mn = hashstr(t, strV(&nn->key));
- if (mn != freenode) {
- freenode->next = nn->next;
- nn->next = mn->next;
- setmref(mn->next, nn);
+ /*
+ ** Nodes after n might have n as their main node, and need rechaining
+ ** back onto n. We make use of the following property of tables: for all
+ ** nodes m, at least one of the following four statements is true:
+ ** 1. tvisnil(&m->key) NB: tvisnil(&m->val) is a stronger statement
+ ** 2. tvisstr(&m->key)
+ ** 3. tvisstr(&main(m)->key)
+ ** 4. main(m) == main(main(m))
+ ** Initially, we need to rechain any nn which has main(nn) == n. As
+ ** main(n) != n (because collide != n earlier), main(nn) == n requires
+ ** either statement 2 or statement 3 to be true about nn.
+ */
+ if (!tvisstr(&n->key)) {
+ /* Statement 3 is not true, so only need to consider string keys. */
+ while ((nn = nextnode(freenode))) {
+ if (tvisstr(&nn->key) && !tvisnil(&nn->val) &&
+ hashstr(t, strV(&nn->key)) == n) {
+ goto rechain;
+ }
+ freenode = nn;
+ }
+ } else {
+ /* Statement 3 is true, so need to consider all types of key. */
+ while ((nn = nextnode(freenode))) {
+ if (!tvisnil(&nn->val) && hashkey(t, &nn->key) == n) {
+ rechain:
+ freenode->next = nn->next;
+ nn->next = n->next;
+ setmref(n->next, nn);
+ /*
+ ** Rechaining one node onto n creates a new dilemma: we now need
+ ** to rechain any nn which has main(nn) == n OR has main(nn) equal
+ ** to any node which has already been rechained. Furthermore, at
+ ** least one of n and n->next will have a string key, so all types
+ ** of nn key need to be considered. Rather than testing whether
+ ** main(nn) definitely _is_ in the new chain, we test whether it
+ ** might _not_ be in the old chain, and if so re-link it into
+ ** the correct chain.
+ */
+ while ((nn = nextnode(freenode))) {
+ if (!tvisnil(&nn->val)) {
+ Node *mn = hashkey(t, &nn->key);
+ if (mn != freenode && mn != nn) {
+ freenode->next = nn->next;
+ nn->next = mn->next;
+ setmref(mn->next, nn);
+ } else {
+ freenode = nn;
+ }
} else {
freenode = nn;
}
- } else {
- freenode = nn;
}
+ break;
+ } else {
+ freenode = nn;
}
- break;
- } else {
- freenode = nn;
}
}
} else { /* Otherwise use free node. */
--
2.21.0