oj 3.13.15 → 3.13.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/ext/oj/buf.h +4 -0
- data/ext/oj/compat.c +10 -10
- data/ext/oj/custom.c +13 -13
- data/ext/oj/dump.c +2 -2
- data/ext/oj/dump_compat.c +5 -5
- data/ext/oj/dump_object.c +3 -3
- data/ext/oj/dump_strict.c +5 -5
- data/ext/oj/extconf.rb +14 -2
- data/ext/oj/object.c +9 -9
- data/ext/oj/oj.c +1 -0
- data/ext/oj/parse.c +112 -80
- data/ext/oj/parse.h +2 -0
- data/ext/oj/parser.c +35 -4
- data/ext/oj/parser.h +1 -0
- data/ext/oj/rails.c +5 -5
- data/ext/oj/saj2.c +299 -45
- data/ext/oj/strict.c +13 -13
- data/ext/oj/validate.c +21 -26
- data/ext/oj/wab.c +15 -15
- data/lib/oj/saj.rb +20 -6
- data/lib/oj/version.rb +1 -1
- data/test/bar.rb +3 -8
- data/test/test_compat.rb +9 -0
- data/test/test_parser_saj.rb +55 -2
- metadata +2 -2
data/ext/oj/parse.c
CHANGED
@@ -183,6 +183,74 @@ static void unicode_to_chars(ParseInfo pi, Buf buf, uint32_t code) {
|
|
183
183
|
}
|
184
184
|
}
|
185
185
|
|
186
|
+
static inline const char *scan_string_noSIMD(const char *str, const char *end) {
|
187
|
+
for (; '"' != *str; str++) {
|
188
|
+
if (end <= str || '\0' == *str || '\\' == *str) {
|
189
|
+
break;
|
190
|
+
}
|
191
|
+
}
|
192
|
+
return str;
|
193
|
+
}
|
194
|
+
|
195
|
+
// Taken from Tensorflow:
|
196
|
+
// https://github.com/tensorflow/tensorflow/blob/5dcfc51118817f27fad5246812d83e5dccdc5f72/tensorflow/core/lib/hash/crc32c_accelerate.cc#L21-L38
|
197
|
+
#ifdef __SSE4_2__
|
198
|
+
#if defined(__x86_64__) && defined(__GNUC__) && \
|
199
|
+
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
200
|
+
#define USE_SSE_DETECT 1
|
201
|
+
#elif defined(__x86_64__) && defined(__clang__)
|
202
|
+
#if __has_builtin(__builtin_cpu_supports)
|
203
|
+
#define USE_SSE_DETECT 1
|
204
|
+
#endif
|
205
|
+
#endif
|
206
|
+
#endif /* __SSE4_2__ */
|
207
|
+
|
208
|
+
// This version of Apple clang has a bug:
|
209
|
+
// https://llvm.org/bugs/show_bug.cgi?id=25510
|
210
|
+
#if defined(__APPLE__) && (__clang_major__ <= 8)
|
211
|
+
#undef USE_SSE_DETECT
|
212
|
+
#endif
|
213
|
+
|
214
|
+
#ifdef USE_SSE_DETECT
|
215
|
+
#include <nmmintrin.h>
|
216
|
+
|
217
|
+
static inline const char *scan_string_SIMD(const char *str, const char *end) {
|
218
|
+
static const char chars[16] = "\x00\\\"";
|
219
|
+
const __m128i terminate = _mm_loadu_si128((const __m128i *)&chars[0]);
|
220
|
+
const char *_end = (const char *)(end - 16);
|
221
|
+
|
222
|
+
for (; str <= _end; str += 16) {
|
223
|
+
const __m128i string = _mm_loadu_si128((const __m128i *)str);
|
224
|
+
const int r = _mm_cmpestri(terminate, 3, string, 16, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT);
|
225
|
+
if (r != 16) {
|
226
|
+
str = (char*)(str + r);
|
227
|
+
return str;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
return scan_string_noSIMD(str, end);
|
232
|
+
}
|
233
|
+
#endif
|
234
|
+
|
235
|
+
static bool cpu_supports_sse42(void) {
|
236
|
+
#if USE_SSE_DETECT
|
237
|
+
__builtin_cpu_init();
|
238
|
+
return (__builtin_cpu_supports("sse4.2"));
|
239
|
+
#else
|
240
|
+
return false;
|
241
|
+
#endif
|
242
|
+
}
|
243
|
+
|
244
|
+
static const char *(*scan_func) (const char *str, const char *end) = scan_string_noSIMD;
|
245
|
+
|
246
|
+
void oj_scanner_init(void) {
|
247
|
+
if (cpu_supports_sse42()) {
|
248
|
+
#if USE_SSE_DETECT
|
249
|
+
scan_func = scan_string_SIMD;
|
250
|
+
#endif
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
186
254
|
// entered at /
|
187
255
|
static void read_escaped_str(ParseInfo pi, const char *start) {
|
188
256
|
struct _buf buf;
|
@@ -192,11 +260,11 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
192
260
|
Val parent = stack_peek(&pi->stack);
|
193
261
|
|
194
262
|
buf_init(&buf);
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
if (
|
263
|
+
buf_append_string(&buf, start, cnt);
|
264
|
+
|
265
|
+
for (s = pi->cur; '"' != *s;) {
|
266
|
+
const char *scanned = scan_func(s, pi->end);
|
267
|
+
if (scanned >= pi->end) {
|
200
268
|
oj_set_error_at(pi,
|
201
269
|
oj_parse_error_class,
|
202
270
|
__FILE__,
|
@@ -204,7 +272,12 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
204
272
|
"quoted string not terminated");
|
205
273
|
buf_cleanup(&buf);
|
206
274
|
return;
|
207
|
-
}
|
275
|
+
}
|
276
|
+
|
277
|
+
buf_append_string(&buf, s, (size_t)(scanned - s));
|
278
|
+
s = scanned;
|
279
|
+
|
280
|
+
if ('\\' == *s) {
|
208
281
|
s++;
|
209
282
|
switch (*s) {
|
210
283
|
case 'n': buf_append(&buf, '\n'); break;
|
@@ -273,8 +346,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
273
346
|
buf_cleanup(&buf);
|
274
347
|
return;
|
275
348
|
}
|
276
|
-
|
277
|
-
buf_append(&buf, *s);
|
349
|
+
s++;
|
278
350
|
}
|
279
351
|
}
|
280
352
|
if (0 == parent) {
|
@@ -327,44 +399,11 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
327
399
|
buf_cleanup(&buf);
|
328
400
|
}
|
329
401
|
|
330
|
-
static inline void scan_string_noSIMD(ParseInfo pi) {
|
331
|
-
for (; '"' != *pi->cur; pi->cur++) {
|
332
|
-
if (pi->end <= pi->cur || '\0' == *pi->cur || '\\' == *pi->cur) {
|
333
|
-
return;
|
334
|
-
}
|
335
|
-
}
|
336
|
-
}
|
337
|
-
|
338
|
-
#if defined(OJ_USE_SSE4_2)
|
339
|
-
#include <nmmintrin.h>
|
340
|
-
|
341
|
-
static inline void scan_string_SIMD(ParseInfo pi) {
|
342
|
-
static const char chars[16] = "\x00\\\"";
|
343
|
-
const __m128i terminate = _mm_loadu_si128((const __m128i *)&chars[0]);
|
344
|
-
const char *end = (const char *)(pi->end - 16);
|
345
|
-
|
346
|
-
for (; pi->cur <= end; pi->cur += 16) {
|
347
|
-
const __m128i string = _mm_loadu_si128((const __m128i *)pi->cur);
|
348
|
-
const int r = _mm_cmpestri(terminate, 3, string, 16, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT);
|
349
|
-
if (r != 16) {
|
350
|
-
pi->cur = (const char*)(pi->cur + r);
|
351
|
-
return;
|
352
|
-
}
|
353
|
-
}
|
354
|
-
|
355
|
-
scan_string_noSIMD(pi);
|
356
|
-
}
|
357
|
-
#endif
|
358
|
-
|
359
402
|
static void read_str(ParseInfo pi) {
|
360
403
|
const char *str = pi->cur;
|
361
404
|
Val parent = stack_peek(&pi->stack);
|
362
405
|
|
363
|
-
|
364
|
-
scan_string_SIMD(pi);
|
365
|
-
#else
|
366
|
-
scan_string_noSIMD(pi);
|
367
|
-
#endif
|
406
|
+
pi->cur = scan_func(pi->cur, pi->end);
|
368
407
|
if (RB_UNLIKELY(pi->end <= pi->cur)) {
|
369
408
|
oj_set_error_at(pi,
|
370
409
|
oj_parse_error_class,
|
@@ -494,33 +533,31 @@ static void read_num(ParseInfo pi) {
|
|
494
533
|
int dec_cnt = 0;
|
495
534
|
bool zero1 = false;
|
496
535
|
|
536
|
+
// Skip leading zeros.
|
537
|
+
for (; '0' == *pi->cur; pi->cur++) {
|
538
|
+
zero1 = true;
|
539
|
+
}
|
540
|
+
|
497
541
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
498
|
-
|
499
|
-
zero1 = true;
|
500
|
-
}
|
501
|
-
if (0 < ni.i) {
|
502
|
-
dec_cnt++;
|
503
|
-
}
|
504
|
-
if (!ni.big) {
|
505
|
-
int d = (*pi->cur - '0');
|
542
|
+
int d = (*pi->cur - '0');
|
506
543
|
|
507
|
-
|
508
|
-
|
509
|
-
oj_set_error_at(pi,
|
510
|
-
oj_parse_error_class,
|
511
|
-
__FILE__,
|
512
|
-
__LINE__,
|
513
|
-
"not a number");
|
514
|
-
return;
|
515
|
-
}
|
516
|
-
zero1 = false;
|
517
|
-
}
|
518
|
-
ni.i = ni.i * 10 + d;
|
519
|
-
if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
|
520
|
-
ni.big = 1;
|
521
|
-
}
|
544
|
+
if (RB_LIKELY(0 != ni.i)) {
|
545
|
+
dec_cnt++;
|
522
546
|
}
|
547
|
+
ni.i = ni.i * 10 + d;
|
548
|
+
}
|
549
|
+
if (RB_UNLIKELY(0 != ni.i && zero1 && CompatMode == pi->options.mode)) {
|
550
|
+
oj_set_error_at(pi,
|
551
|
+
oj_parse_error_class,
|
552
|
+
__FILE__,
|
553
|
+
__LINE__,
|
554
|
+
"not a number");
|
555
|
+
return;
|
556
|
+
}
|
557
|
+
if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
|
558
|
+
ni.big = true;
|
523
559
|
}
|
560
|
+
|
524
561
|
if ('.' == *pi->cur) {
|
525
562
|
pi->cur++;
|
526
563
|
// A trailing . is not a valid decimal but if encountered allow it
|
@@ -540,25 +577,20 @@ static void read_num(ParseInfo pi) {
|
|
540
577
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
541
578
|
int d = (*pi->cur - '0');
|
542
579
|
|
543
|
-
if (0
|
580
|
+
if (RB_LIKELY(0 != ni.num || 0 != ni.i)) {
|
544
581
|
dec_cnt++;
|
545
582
|
}
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
}
|
550
|
-
} else {
|
551
|
-
ni.num = ni.num * 10 + d;
|
552
|
-
ni.div *= 10;
|
553
|
-
ni.di++;
|
554
|
-
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
555
|
-
if (!ni.no_big) {
|
556
|
-
ni.big = true;
|
557
|
-
}
|
558
|
-
}
|
559
|
-
}
|
583
|
+
ni.num = ni.num * 10 + d;
|
584
|
+
ni.div *= 10;
|
585
|
+
ni.di++;
|
560
586
|
}
|
561
587
|
}
|
588
|
+
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
589
|
+
if (!ni.no_big) {
|
590
|
+
ni.big = true;
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
562
594
|
if ('e' == *pi->cur || 'E' == *pi->cur) {
|
563
595
|
int eneg = 0;
|
564
596
|
|
data/ext/oj/parse.h
CHANGED
data/ext/oj/parser.c
CHANGED
@@ -533,6 +533,7 @@ static void calc_num(ojParser p) {
|
|
533
533
|
// nothing to do
|
534
534
|
break;
|
535
535
|
}
|
536
|
+
p->type = OJ_NONE;
|
536
537
|
}
|
537
538
|
|
538
539
|
static void big_change(ojParser p) {
|
@@ -598,6 +599,8 @@ static void parse(ojParser p, const byte *json) {
|
|
598
599
|
const byte *b = json;
|
599
600
|
int i;
|
600
601
|
|
602
|
+
p->line = 1;
|
603
|
+
p->col = -1;
|
601
604
|
#if DEBUG
|
602
605
|
printf("*** parse - mode: %c %s\n", p->map[256], (const char *)json);
|
603
606
|
#endif
|
@@ -652,6 +655,7 @@ static void parse(ojParser p, const byte *json) {
|
|
652
655
|
}
|
653
656
|
buf_append_string(&p->buf, (const char *)start, b - start);
|
654
657
|
if ('"' == *b) {
|
658
|
+
p->cur = b - json;
|
655
659
|
p->funcs[p->stack[p->depth]].add_str(p);
|
656
660
|
p->map = (0 == p->depth) ? value_map : after_map;
|
657
661
|
break;
|
@@ -661,12 +665,14 @@ static void parse(ojParser p, const byte *json) {
|
|
661
665
|
p->next_map = (0 == p->depth) ? value_map : after_map;
|
662
666
|
break;
|
663
667
|
case OPEN_OBJECT:
|
668
|
+
p->cur = b - json;
|
664
669
|
p->funcs[p->stack[p->depth]].open_object(p);
|
665
670
|
p->depth++;
|
666
671
|
p->stack[p->depth] = OBJECT_FUN;
|
667
672
|
p->map = key1_map;
|
668
673
|
break;
|
669
674
|
case NUM_CLOSE_OBJECT:
|
675
|
+
p->cur = b - json;
|
670
676
|
calc_num(p);
|
671
677
|
// flow through
|
672
678
|
case CLOSE_OBJECT:
|
@@ -677,15 +683,18 @@ static void parse(ojParser p, const byte *json) {
|
|
677
683
|
return;
|
678
684
|
}
|
679
685
|
p->depth--;
|
686
|
+
p->cur = b - json;
|
680
687
|
p->funcs[p->stack[p->depth]].close_object(p);
|
681
688
|
break;
|
682
689
|
case OPEN_ARRAY:
|
690
|
+
p->cur = b - json;
|
683
691
|
p->funcs[p->stack[p->depth]].open_array(p);
|
684
692
|
p->depth++;
|
685
693
|
p->stack[p->depth] = ARRAY_FUN;
|
686
694
|
p->map = value_map;
|
687
695
|
break;
|
688
696
|
case NUM_CLOSE_ARRAY:
|
697
|
+
p->cur = b - json;
|
689
698
|
calc_num(p);
|
690
699
|
// flow through
|
691
700
|
case CLOSE_ARRAY:
|
@@ -696,9 +705,11 @@ static void parse(ojParser p, const byte *json) {
|
|
696
705
|
return;
|
697
706
|
}
|
698
707
|
p->depth--;
|
708
|
+
p->cur = b - json;
|
699
709
|
p->funcs[p->stack[p->depth]].close_array(p);
|
700
710
|
break;
|
701
711
|
case NUM_COMMA:
|
712
|
+
p->cur = b - json;
|
702
713
|
calc_num(p);
|
703
714
|
if (0 < p->depth && OBJECT_FUN == p->stack[p->depth]) {
|
704
715
|
p->map = key_map;
|
@@ -860,8 +871,14 @@ static void parse(ojParser p, const byte *json) {
|
|
860
871
|
b--;
|
861
872
|
p->map = big_exp_map;
|
862
873
|
break;
|
863
|
-
case NUM_SPC:
|
864
|
-
|
874
|
+
case NUM_SPC:
|
875
|
+
p->cur = b - json;
|
876
|
+
calc_num(p);
|
877
|
+
break;
|
878
|
+
case NUM_NEWLINE:
|
879
|
+
p->cur = b - json;
|
880
|
+
calc_num(p);
|
881
|
+
b++;
|
865
882
|
#ifdef SPACE_JUMP
|
866
883
|
// for (uint32_t *sj = (uint32_t*)b; 0x20202020 == *sj; sj++) { b += 4; }
|
867
884
|
for (uint16_t *sj = (uint16_t *)b; 0x2020 == *sj; sj++) {
|
@@ -882,6 +899,7 @@ static void parse(ojParser p, const byte *json) {
|
|
882
899
|
buf_append_string(&p->buf, (const char *)start, b - start);
|
883
900
|
}
|
884
901
|
if ('"' == *b) {
|
902
|
+
p->cur = b - json;
|
885
903
|
p->funcs[p->stack[p->depth]].add_str(p);
|
886
904
|
p->map = p->next_map;
|
887
905
|
break;
|
@@ -890,6 +908,7 @@ static void parse(ojParser p, const byte *json) {
|
|
890
908
|
break;
|
891
909
|
case STR_SLASH: p->map = esc_map; break;
|
892
910
|
case STR_QUOTE:
|
911
|
+
p->cur = b - json;
|
893
912
|
p->funcs[p->stack[p->depth]].add_str(p);
|
894
913
|
p->map = p->next_map;
|
895
914
|
break;
|
@@ -967,6 +986,7 @@ static void parse(ojParser p, const byte *json) {
|
|
967
986
|
case VAL_NULL:
|
968
987
|
if ('u' == b[1] && 'l' == b[2] && 'l' == b[3]) {
|
969
988
|
b += 3;
|
989
|
+
p->cur = b - json;
|
970
990
|
p->funcs[p->stack[p->depth]].add_null(p);
|
971
991
|
p->map = (0 == p->depth) ? value_map : after_map;
|
972
992
|
break;
|
@@ -992,6 +1012,7 @@ static void parse(ojParser p, const byte *json) {
|
|
992
1012
|
case VAL_TRUE:
|
993
1013
|
if ('r' == b[1] && 'u' == b[2] && 'e' == b[3]) {
|
994
1014
|
b += 3;
|
1015
|
+
p->cur = b - json;
|
995
1016
|
p->funcs[p->stack[p->depth]].add_true(p);
|
996
1017
|
p->map = (0 == p->depth) ? value_map : after_map;
|
997
1018
|
break;
|
@@ -1017,6 +1038,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1017
1038
|
case VAL_FALSE:
|
1018
1039
|
if ('a' == b[1] && 'l' == b[2] && 's' == b[3] && 'e' == b[4]) {
|
1019
1040
|
b += 4;
|
1041
|
+
p->cur = b - json;
|
1020
1042
|
p->funcs[p->stack[p->depth]].add_false(p);
|
1021
1043
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1022
1044
|
break;
|
@@ -1050,6 +1072,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1050
1072
|
parse_error(p, "expected null");
|
1051
1073
|
return;
|
1052
1074
|
}
|
1075
|
+
p->cur = b - json;
|
1053
1076
|
p->funcs[p->stack[p->depth]].add_null(p);
|
1054
1077
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1055
1078
|
}
|
@@ -1061,6 +1084,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1061
1084
|
parse_error(p, "expected false");
|
1062
1085
|
return;
|
1063
1086
|
}
|
1087
|
+
p->cur = b - json;
|
1064
1088
|
p->funcs[p->stack[p->depth]].add_false(p);
|
1065
1089
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1066
1090
|
}
|
@@ -1072,6 +1096,7 @@ static void parse(ojParser p, const byte *json) {
|
|
1072
1096
|
parse_error(p, "expected true");
|
1073
1097
|
return;
|
1074
1098
|
}
|
1099
|
+
p->cur = b - json;
|
1075
1100
|
p->funcs[p->stack[p->depth]].add_true(p);
|
1076
1101
|
p->map = (0 == p->depth) ? value_map : after_map;
|
1077
1102
|
}
|
@@ -1089,6 +1114,9 @@ static void parse(ojParser p, const byte *json) {
|
|
1089
1114
|
p->map = trail_map;
|
1090
1115
|
}
|
1091
1116
|
}
|
1117
|
+
if (0 < p->depth) {
|
1118
|
+
parse_error(p, "parse error, not closed");
|
1119
|
+
}
|
1092
1120
|
if (0 == p->depth) {
|
1093
1121
|
switch (p->map[256]) {
|
1094
1122
|
case '0':
|
@@ -1099,7 +1127,10 @@ static void parse(ojParser p, const byte *json) {
|
|
1099
1127
|
case 'D':
|
1100
1128
|
case 'g':
|
1101
1129
|
case 'B':
|
1102
|
-
case 'Y':
|
1130
|
+
case 'Y':
|
1131
|
+
p->cur = b - json;
|
1132
|
+
calc_num(p);
|
1133
|
+
break;
|
1103
1134
|
}
|
1104
1135
|
}
|
1105
1136
|
return;
|
@@ -1456,7 +1487,7 @@ static VALUE saj_parser = Qundef;
|
|
1456
1487
|
/* Document-method: saj
|
1457
1488
|
* call-seq: saj
|
1458
1489
|
*
|
1459
|
-
* Returns the default
|
1490
|
+
* Returns the default SAJ parser. Note the default SAJ parser can not be used
|
1460
1491
|
* concurrently in more than one thread.
|
1461
1492
|
*/
|
1462
1493
|
static VALUE parser_saj(VALUE self) {
|
data/ext/oj/parser.h
CHANGED
data/ext/oj/rails.c
CHANGED
@@ -517,7 +517,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
517
517
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
518
518
|
volatile VALUE ja;
|
519
519
|
|
520
|
-
if (Yes == out->opts->trace) {
|
520
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
521
521
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
522
522
|
}
|
523
523
|
// Some classes elect to not take an options argument so check the arity
|
@@ -527,7 +527,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
527
527
|
} else {
|
528
528
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
529
529
|
}
|
530
|
-
if (Yes == out->opts->trace) {
|
530
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
531
531
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
532
532
|
}
|
533
533
|
|
@@ -1464,7 +1464,7 @@ static DumpFunc rails_funcs[] = {
|
|
1464
1464
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1465
1465
|
int type = rb_type(obj);
|
1466
1466
|
|
1467
|
-
if (Yes == out->opts->trace) {
|
1467
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1468
1468
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1469
1469
|
}
|
1470
1470
|
if (MAX_DEPTH < depth) {
|
@@ -1475,14 +1475,14 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1475
1475
|
|
1476
1476
|
if (NULL != f) {
|
1477
1477
|
f(obj, depth, out, as_ok);
|
1478
|
-
if (Yes == out->opts->trace) {
|
1478
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1479
1479
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1480
1480
|
}
|
1481
1481
|
return;
|
1482
1482
|
}
|
1483
1483
|
}
|
1484
1484
|
oj_dump_nil(Qnil, depth, out, false);
|
1485
|
-
if (Yes == out->opts->trace) {
|
1485
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1486
1486
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1487
1487
|
}
|
1488
1488
|
}
|