oj 3.14.1 → 3.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/oj/mem.c ADDED
@@ -0,0 +1,324 @@
1
+ // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
+
3
+ #include <pthread.h>
4
+ #include <stdbool.h>
5
+ #include <stdint.h>
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+
10
+ #include <ruby.h>
11
+
12
+ #include "mem.h"
13
+
14
+ typedef struct _rec {
15
+ struct _rec *next;
16
+ const void *ptr;
17
+ size_t size;
18
+ const char *file;
19
+ int line;
20
+ bool ruby;
21
+ } *Rec;
22
+
23
+ typedef struct _rep {
24
+ struct _rep *next;
25
+ size_t size;
26
+ const char *file;
27
+ int line;
28
+ int cnt;
29
+ } *Rep;
30
+
31
+ #ifdef MEM_DEBUG
32
+
33
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
34
+ static Rec recs = NULL;
35
+ static const char mem_pad[] = "--- This is a memory pad and should not change until being freed. ---";
36
+
37
+ void*
38
+ oj_malloc(size_t size, const char *file, int line) {
39
+ void *ptr = malloc(size + sizeof(mem_pad));
40
+
41
+ if (NULL != ptr) {
42
+ Rec r = (Rec)malloc(sizeof(struct _rec));
43
+
44
+ if (NULL != r) {
45
+ strcpy(((char*)ptr) + size, mem_pad);
46
+ r->ptr = ptr;
47
+ r->size = size;
48
+ r->file = file;
49
+ r->line = line;
50
+ r->ruby = false;
51
+ pthread_mutex_lock(&lock);
52
+ r->next = recs;
53
+ recs = r;
54
+ pthread_mutex_unlock(&lock);
55
+ } else {
56
+ free(ptr);
57
+ ptr = NULL;
58
+ }
59
+ }
60
+ return ptr;
61
+ }
62
+
63
+ void*
64
+ oj_realloc(void *orig, size_t size, const char *file, int line) {
65
+ void *ptr = realloc(orig, size + sizeof(mem_pad));
66
+ Rec r;
67
+
68
+ if (NULL != ptr) {
69
+ strcpy(((char*)ptr) + size, mem_pad);
70
+ pthread_mutex_lock(&lock);
71
+ for (r = recs; NULL != r; r = r->next) {
72
+ if (orig == r->ptr) {
73
+ r->ptr = ptr;
74
+ r->size = size;
75
+ r->file = file;
76
+ r->line = line;
77
+ r->ruby = false;
78
+ break;
79
+ }
80
+ }
81
+ pthread_mutex_unlock(&lock);
82
+ if (NULL == r) {
83
+ printf("Realloc at %s:%d (%p) not allocated.\n", file, line, orig);
84
+ }
85
+ }
86
+ return ptr;
87
+ }
88
+
89
+ void*
90
+ oj_calloc(size_t count, size_t size, const char *file, int line) {
91
+ void *ptr;
92
+
93
+ size *= count;
94
+ if (NULL != (ptr = malloc(size + sizeof(mem_pad)))) {
95
+ Rec r = (Rec)malloc(sizeof(struct _rec));
96
+
97
+ if (NULL != r) {
98
+ memset(ptr, 0, size);
99
+ strcpy(((char*)ptr) + size, mem_pad);
100
+ r->ptr = ptr;
101
+ r->size = size;
102
+ r->file = file;
103
+ r->line = line;
104
+ r->ruby = false;
105
+ pthread_mutex_lock(&lock);
106
+ r->next = recs;
107
+ recs = r;
108
+ pthread_mutex_unlock(&lock);
109
+ } else {
110
+ free(ptr);
111
+ ptr = NULL;
112
+ }
113
+ }
114
+ return ptr;
115
+ }
116
+
117
+ void*
118
+ oj_r_alloc(size_t size, const char *file, int line) {
119
+ void *ptr = ruby_xmalloc(size + sizeof(mem_pad));
120
+
121
+ if (NULL != ptr) {
122
+ Rec r = (Rec)malloc(sizeof(struct _rec));
123
+
124
+ if (NULL != r) {
125
+ strcpy(((char*)ptr) + size, mem_pad);
126
+ r->ptr = ptr;
127
+ r->size = size;
128
+ r->file = file;
129
+ r->line = line;
130
+ r->ruby = true;
131
+ pthread_mutex_lock(&lock);
132
+ r->next = recs;
133
+ recs = r;
134
+ pthread_mutex_unlock(&lock);
135
+ } else {
136
+ free(ptr);
137
+ ptr = NULL;
138
+ }
139
+ }
140
+ return ptr;
141
+ }
142
+
143
+ void*
144
+ oj_r_realloc(void *orig, size_t size, const char *file, int line) {
145
+ void *ptr = ruby_xrealloc2(orig, 1, size + sizeof(mem_pad));
146
+ Rec r;
147
+
148
+ if (NULL != ptr) {
149
+ strcpy(((char*)ptr) + size, mem_pad);
150
+ pthread_mutex_lock(&lock);
151
+ for (r = recs; NULL != r; r = r->next) {
152
+ if (orig == r->ptr) {
153
+ r->ptr = ptr;
154
+ r->size = size;
155
+ r->file = file;
156
+ r->line = line;
157
+ r->ruby = true;
158
+ break;
159
+ }
160
+ }
161
+ pthread_mutex_unlock(&lock);
162
+ if (NULL == r) {
163
+ printf("Realloc at %s:%d (%p) not allocated.\n", file, line, orig);
164
+ }
165
+ }
166
+ return ptr;
167
+ }
168
+
169
+
170
+ void
171
+ oj_freed(void *ptr, const char *file, int line, bool ruby) {
172
+ if (NULL != ptr) {
173
+ Rec r = NULL;
174
+ Rec prev = NULL;
175
+
176
+ pthread_mutex_lock(&lock);
177
+ for (r = recs; NULL != r; r = r->next) {
178
+ if (ptr == r->ptr) {
179
+ if (NULL == prev) {
180
+ recs = r->next;
181
+ } else {
182
+ prev->next = r->next;
183
+ }
184
+ break;
185
+ }
186
+ prev = r;
187
+ }
188
+ pthread_mutex_unlock(&lock);
189
+ if (NULL == r) {
190
+ printf("Free at %s:%d (%p) not allocated or already freed.\n", file, line, ptr);
191
+ } else {
192
+ char *pad = (char*)r->ptr + r->size;
193
+
194
+ if (r->ruby != ruby) {
195
+ if (r->ruby) {
196
+ printf("Memory at %s:%d (%p) allocated with Ruby allocator and freed with stdlib free.\n", file, line, ptr);
197
+ } else {
198
+ printf("Memory at %s:%d (%p) allocated with stdlib allocator and freed with Ruby free.\n", file, line, ptr);
199
+ }
200
+ }
201
+ if (0 != strcmp(mem_pad, pad)) {
202
+ uint8_t *p;
203
+ uint8_t *end = (uint8_t*)pad + sizeof(mem_pad);
204
+
205
+ printf("Memory at %s:%d (%p) write outside allocated.\n", file, line, ptr);
206
+ for (p = (uint8_t*)pad; p < end; p++) {
207
+ if (0x20 < *p && *p < 0x7f) {
208
+ printf("%c ", *p);
209
+ } else {
210
+ printf("%02x ", *(uint8_t*)p);
211
+ }
212
+ }
213
+ printf("\n");
214
+ }
215
+ free(r);
216
+ }
217
+ }
218
+ }
219
+
220
+ void
221
+ oj_r_free(void *ptr, const char *file, int line) {
222
+ oj_freed(ptr, file, line, true);
223
+ xfree(ptr);
224
+ }
225
+
226
+
227
+ void
228
+ oj_free(void *ptr, const char *file, int line) {
229
+ oj_freed(ptr, file, line, false);
230
+ free(ptr);
231
+ }
232
+
233
+ char*
234
+ oj_mem_strdup(const char *str, const char *file, int line) {
235
+ size_t size = strlen(str) + 1;
236
+ char *ptr = (char*)malloc(size + sizeof(mem_pad));
237
+
238
+ if (NULL != ptr) {
239
+ Rec r = (Rec)malloc(sizeof(struct _rec));
240
+
241
+ if (NULL != r) {
242
+ strcpy(ptr, str);
243
+ strcpy(((char*)ptr) + size, mem_pad);
244
+ r->ptr = (void*)ptr;
245
+ r->size = size;
246
+ r->file = file;
247
+ r->line = line;
248
+ r->ruby = false;
249
+ pthread_mutex_lock(&lock);
250
+ r->next = recs;
251
+ recs = r;
252
+ pthread_mutex_unlock(&lock);
253
+ } else {
254
+ free(ptr);
255
+ ptr = NULL;
256
+ }
257
+ }
258
+ return ptr;
259
+ }
260
+
261
+ #endif
262
+
263
+ #ifdef MEM_DEBUG
264
+
265
+ static Rep
266
+ update_reps(Rep reps, Rec r) {
267
+ Rep rp = reps;
268
+
269
+ for (; NULL != rp; rp = rp->next) {
270
+ if (rp->line == r->line && (rp->file == r->file || 0 == strcmp(rp->file, r->file))) {
271
+ rp->size += r->size;
272
+ rp->cnt++;
273
+ break;
274
+ }
275
+ }
276
+ if (NULL == rp &&
277
+ NULL != (rp = (Rep)malloc(sizeof(struct _rep)))) {
278
+ rp->size = r->size;
279
+ rp->file = r->file;
280
+ rp->line = r->line;
281
+ rp->cnt = 1;
282
+ rp->next = reps;
283
+ reps = rp;
284
+ }
285
+ return reps;
286
+ }
287
+
288
+ static void
289
+ print_stats() {
290
+ printf("\n--- Memory Usage Report --------------------------------------------------------\n");
291
+ pthread_mutex_lock(&lock);
292
+
293
+ if (NULL == recs) {
294
+ printf("No memory leaks\n");
295
+ } else {
296
+ Rep reps = NULL;
297
+ Rep rp;
298
+ Rec r;
299
+ size_t leaked = 0;
300
+
301
+ for (r = recs; NULL != r; r = r->next) {
302
+ reps = update_reps(reps, r);
303
+ }
304
+ while (NULL != (rp = reps)) {
305
+ reps = rp->next;
306
+ printf("%16s:%3d %8lu bytes over %d occurances allocated and not freed.\n", rp->file, rp->line, rp->size, rp->cnt);
307
+ leaked += rp->size;
308
+ free(rp);
309
+ }
310
+ printf("%lu bytes leaked\n", leaked);
311
+ }
312
+ pthread_mutex_unlock(&lock);
313
+ printf("--------------------------------------------------------------------------------\n");
314
+ }
315
+
316
+ #endif
317
+
318
+ void
319
+ oj_mem_report() {
320
+ #ifdef MEM_DEBUG
321
+ rb_gc();
322
+ print_stats();
323
+ #endif
324
+ }
data/ext/oj/mem.h ADDED
@@ -0,0 +1,53 @@
1
+ // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
+
3
+ #ifndef OJ_MEM_H
4
+ #define OJ_MEM_H
5
+
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+
10
+ #ifdef MEM_DEBUG
11
+
12
+ #define OJ_MALLOC(size) oj_malloc(size, __FILE__, __LINE__)
13
+ #define OJ_REALLOC(ptr, size) oj_realloc(ptr, size, __FILE__, __LINE__)
14
+ #define OJ_CALLOC(count, size) oj_calloc(count, size, __FILE__, __LINE__)
15
+ #define OJ_FREE(ptr) oj_free(ptr, __FILE__, __LINE__)
16
+
17
+ #define OJ_R_ALLOC(type) oj_r_alloc(sizeof(type), __FILE__, __LINE__)
18
+ #define OJ_R_ALLOC_N(type, n) (type *)oj_r_alloc(sizeof(type) * (n), __FILE__, __LINE__)
19
+ #define OJ_R_REALLOC_N(ptr, type, n) ((ptr) = (type*)oj_r_realloc(ptr, (sizeof(type) * (n)), __FILE__, __LINE__))
20
+ #define OJ_R_FREE(ptr) oj_r_free(ptr, __FILE__, __LINE__)
21
+
22
+ #define OJ_STRDUP(str) oj_mem_strdup(str, __FILE__, __LINE__)
23
+
24
+ extern void* oj_malloc(size_t size, const char *file, int line);
25
+ extern void* oj_realloc(void *ptr, size_t size, const char *file, int line);
26
+ extern void* oj_calloc(size_t count, size_t size, const char *file, int line);
27
+ extern void oj_free(void *ptr, const char *file, int line);
28
+
29
+ extern void* oj_r_alloc(size_t size, const char *file, int line);
30
+ extern void* oj_r_realloc(void *ptr, size_t size, const char *file, int line);
31
+ extern void oj_r_free(void *ptr, const char *file, int line);
32
+
33
+ extern char* oj_mem_strdup(const char *str, const char *file, int line);
34
+
35
+ #else
36
+
37
+ #define OJ_MALLOC(size) malloc(size)
38
+ #define OJ_REALLOC(ptr, size) realloc(ptr, size)
39
+ #define OJ_CALLOC(count, size) calloc(count, size)
40
+ #define OJ_FREE(ptr) free(ptr)
41
+
42
+ #define OJ_R_ALLOC(type) RB_ALLOC(type)
43
+ #define OJ_R_ALLOC_N(type, n) RB_ALLOC_N(type, n)
44
+ #define OJ_R_REALLOC_N(ptr, type, n) RB_REALLOC_N(ptr, type, n)
45
+ #define OJ_R_FREE(ptr) xfree(ptr)
46
+
47
+ #define OJ_STRDUP(str) strdup(str)
48
+
49
+ #endif
50
+
51
+ extern void oj_mem_report();
52
+
53
+ #endif /* OJ_MEM_H */
data/ext/oj/mimic_json.c CHANGED
@@ -1,6 +1,7 @@
1
1
  // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
2
2
  // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
3
 
4
+ #include "mem.h"
4
5
  #include "dump.h"
5
6
  #include "encode.h"
6
7
  #include "oj.h"
@@ -664,7 +665,7 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
664
665
 
665
666
  if (NULL != oj_default_options.create_id) {
666
667
  if (oj_json_class != oj_default_options.create_id) {
667
- xfree((char *)oj_default_options.create_id);
668
+ OJ_R_FREE((char *)oj_default_options.create_id);
668
669
  }
669
670
  oj_default_options.create_id = NULL;
670
671
  oj_default_options.create_id_len = 0;
@@ -672,7 +673,7 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
672
673
  if (Qnil != id) {
673
674
  size_t len = RSTRING_LEN(id) + 1;
674
675
 
675
- oj_default_options.create_id = ALLOC_N(char, len);
676
+ oj_default_options.create_id = OJ_R_ALLOC_N(char, len);
676
677
  strcpy((char *)oj_default_options.create_id, StringValuePtr(id));
677
678
  oj_default_options.create_id_len = len - 1;
678
679
  }
data/ext/oj/object.c CHANGED
@@ -352,7 +352,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
352
352
  }
353
353
  return 1;
354
354
  } else if (3 <= klen && '#' == key[1]) {
355
- volatile VALUE *a;
355
+ volatile const VALUE *a;
356
356
 
357
357
  if (2 != len) {
358
358
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
@@ -546,7 +546,7 @@ WHICH_TYPE:
546
546
  } else {
547
547
  if (3 <= klen && '^' == *key && '#' == key[1] && T_ARRAY == rb_type(value)) {
548
548
  long len = RARRAY_LEN(value);
549
- volatile VALUE *a = RARRAY_CONST_PTR(value);
549
+ volatile const VALUE *a = RARRAY_CONST_PTR(value);
550
550
 
551
551
  if (2 != len) {
552
552
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
data/ext/oj/odd.c CHANGED
@@ -1,6 +1,7 @@
1
1
  // Copyright (c) 2011 Peter Ohler. All rights reserved.
2
2
  // Licensed under the MIT License. See LICENSE file in the project root for license details.
3
3
 
4
+ #include "mem.h"
4
5
  #include "odd.h"
5
6
 
6
7
  #include <string.h>
@@ -68,7 +69,7 @@ void print_all_odds(const char *label) {
68
69
  }
69
70
 
70
71
  static Odd odd_create(void) {
71
- Odd odd = ALLOC(struct _odd);
72
+ Odd odd = OJ_R_ALLOC(struct _odd);
72
73
 
73
74
  memset(odd, 0, sizeof(struct _odd));
74
75
  odd->next = odds;
@@ -172,7 +173,7 @@ Odd oj_get_oddc(const char *classname, size_t len) {
172
173
  }
173
174
 
174
175
  OddArgs oj_odd_alloc_args(Odd odd) {
175
- OddArgs oa = ALLOC_N(struct _oddArgs, 1);
176
+ OddArgs oa = OJ_R_ALLOC_N(struct _oddArgs, 1);
176
177
  VALUE *a;
177
178
  int i;
178
179
 
@@ -184,7 +185,7 @@ OddArgs oj_odd_alloc_args(Odd odd) {
184
185
  }
185
186
 
186
187
  void oj_odd_free(OddArgs args) {
187
- xfree(args);
188
+ OJ_R_FREE(args);
188
189
  }
189
190
 
190
191
  int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
@@ -210,7 +211,7 @@ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt,
210
211
  odd = odd_create();
211
212
  odd->clas = clas;
212
213
  rb_gc_register_mark_object(odd->clas);
213
- if (NULL == (odd->classname = strdup(rb_class2name(clas)))) {
214
+ if (NULL == (odd->classname = OJ_STRDUP(rb_class2name(clas)))) {
214
215
  rb_raise(rb_eNoMemError, "for class name.");
215
216
  }
216
217
  odd->clen = strlen(odd->classname);
@@ -224,13 +225,13 @@ void oj_reg_odd(VALUE clas, VALUE create_object, VALUE create_method, int mcnt,
224
225
  *fp = 0;
225
226
  switch (rb_type(*members)) {
226
227
  case T_STRING:
227
- if (NULL == (*np = strdup(RSTRING_PTR(*members)))) {
228
+ if (NULL == (*np = OJ_STRDUP(RSTRING_PTR(*members)))) {
228
229
  rb_raise(rb_eNoMemError, "for attribute name.");
229
230
  }
230
231
  break;
231
232
  case T_SYMBOL:
232
233
  // The symbol can move and invalidate the name so make a copy.
233
- if (NULL == (*np = strdup(rb_id2name(SYM2ID(*members))))) {
234
+ if (NULL == (*np = OJ_STRDUP(rb_id2name(SYM2ID(*members))))) {
234
235
  rb_raise(rb_eNoMemError, "for attribute name.");
235
236
  }
236
237
  break;
data/ext/oj/oj.c CHANGED
@@ -11,6 +11,7 @@
11
11
  #include <sys/types.h>
12
12
  #include <unistd.h>
13
13
 
14
+ #include "mem.h"
14
15
  #include "dump.h"
15
16
  #include "encode.h"
16
17
  #include "intern.h"
@@ -782,7 +783,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
782
783
  } else if (create_id_sym == k) {
783
784
  if (Qnil == v) {
784
785
  if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
785
- xfree((char *)oj_default_options.create_id);
786
+ OJ_R_FREE((char *)oj_default_options.create_id);
786
787
  }
787
788
  copts->create_id = NULL;
788
789
  copts->create_id_len = 0;
@@ -791,7 +792,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
791
792
 
792
793
  len = RSTRING_LEN(v);
793
794
  if (len != copts->create_id_len || 0 != strcmp(copts->create_id, str)) {
794
- copts->create_id = ALLOC_N(char, len + 1);
795
+ copts->create_id = OJ_R_ALLOC_N(char, len + 1);
795
796
  strcpy((char *)copts->create_id, str);
796
797
  copts->create_id_len = len;
797
798
  }
@@ -911,7 +912,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
911
912
  copts->array_class = v;
912
913
  }
913
914
  } else if (ignore_sym == k) {
914
- xfree(copts->ignore);
915
+ OJ_R_FREE(copts->ignore);
915
916
  copts->ignore = NULL;
916
917
  if (Qnil != v) {
917
918
  int cnt;
@@ -921,7 +922,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
921
922
  if (0 < cnt) {
922
923
  int i;
923
924
 
924
- copts->ignore = ALLOC_N(VALUE, cnt + 1);
925
+ copts->ignore = OJ_R_ALLOC_N(VALUE, cnt + 1);
925
926
  for (i = 0; i < cnt; i++) {
926
927
  copts->ignore[i] = RARRAY_AREF(v, i);
927
928
  }
@@ -1159,7 +1160,7 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
1159
1160
  WCHAR *wide_path;
1160
1161
  wide_path = rb_w32_mbstr_to_wstr(CP_UTF8, path, -1, NULL);
1161
1162
  fd = rb_w32_wopen(wide_path, O_RDONLY);
1162
- free(wide_path);
1163
+ OJ_FREE(wide_path);
1163
1164
  }
1164
1165
  #else
1165
1166
  fd = open(path, O_RDONLY);
@@ -1724,6 +1725,10 @@ debug_odd(VALUE self, VALUE label) {
1724
1725
  return Qnil;
1725
1726
  }
1726
1727
 
1728
+ static VALUE mem_report(VALUE self) {
1729
+ oj_mem_report();
1730
+ return Qnil;
1731
+ }
1727
1732
 
1728
1733
  /* Document-module: Oj
1729
1734
  *
@@ -1812,6 +1817,8 @@ void Init_oj(void) {
1812
1817
 
1813
1818
  rb_define_module_function(Oj, "optimize_rails", oj_optimize_rails, 0);
1814
1819
 
1820
+ rb_define_module_function(Oj, "mem_report", mem_report, 0);
1821
+
1815
1822
  oj_add_value_id = rb_intern("add_value");
1816
1823
  oj_array_append_id = rb_intern("array_append");
1817
1824
  oj_array_end_id = rb_intern("array_end");
data/ext/oj/parse.c CHANGED
@@ -10,6 +10,7 @@
10
10
  #include <string.h>
11
11
  #include <unistd.h>
12
12
 
13
+ #include "mem.h"
13
14
  #include "buf.h"
14
15
  #include "encode.h"
15
16
  #include "oj.h"
@@ -87,7 +88,7 @@ static void add_value(ParseInfo pi, VALUE rval) {
87
88
  pi->hash_set_value(pi, parent, rval);
88
89
  if (0 != parent->key && 0 < parent->klen &&
89
90
  (parent->key < pi->json || pi->cur < parent->key)) {
90
- xfree((char *)parent->key);
91
+ OJ_R_FREE((char *)parent->key);
91
92
  parent->key = 0;
92
93
  }
93
94
  parent->next = NEXT_HASH_COMMA;
@@ -236,7 +237,8 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
236
237
 
237
238
  for (s = pi->cur; '"' != *s;) {
238
239
  const char *scanned = scan_func(s, pi->end);
239
- if (scanned >= pi->end || '\0' == *s) {
240
+ if (scanned >= pi->end || '\0' == *scanned) {
241
+ //if (scanned >= pi->end) {
240
242
  oj_set_error_at(pi,
241
243
  oj_parse_error_class,
242
244
  __FILE__,
@@ -333,7 +335,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
333
335
  case NEXT_HASH_KEY:
334
336
  if (Qundef == (parent->key_val = pi->hash_key(pi, buf.head, buf_len(&buf)))) {
335
337
  parent->klen = buf_len(&buf);
336
- parent->key = malloc(parent->klen + 1);
338
+ parent->key = OJ_MALLOC(parent->klen + 1);
337
339
  memcpy((char *)parent->key, buf.head, parent->klen);
338
340
  *(char *)(parent->key + parent->klen) = '\0';
339
341
  } else {
@@ -347,7 +349,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
347
349
  pi->hash_set_cstr(pi, parent, buf.head, buf_len(&buf), start);
348
350
  if (0 != parent->key && 0 < parent->klen &&
349
351
  (parent->key < pi->json || pi->cur < parent->key)) {
350
- xfree((char *)parent->key);
352
+ OJ_R_FREE((char *)parent->key);
351
353
  parent->key = 0;
352
354
  }
353
355
  parent->next = NEXT_HASH_COMMA;
@@ -417,7 +419,7 @@ static void read_str(ParseInfo pi) {
417
419
  pi->hash_set_cstr(pi, parent, str, pi->cur - str, str);
418
420
  if (0 != parent->key && 0 < parent->klen &&
419
421
  (parent->key < pi->json || pi->cur < parent->key)) {
420
- xfree((char *)parent->key);
422
+ OJ_R_FREE((char *)parent->key);
421
423
  parent->key = 0;
422
424
  }
423
425
  parent->next = NEXT_HASH_COMMA;
@@ -616,7 +618,7 @@ static void read_num(ParseInfo pi) {
616
618
  pi->hash_set_num(pi, parent, &ni);
617
619
  if (0 != parent->key && 0 < parent->klen &&
618
620
  (parent->key < pi->json || pi->cur < parent->key)) {
619
- xfree((char *)parent->key);
621
+ OJ_R_FREE((char *)parent->key);
620
622
  parent->key = 0;
621
623
  }
622
624
  parent->next = NEXT_HASH_COMMA;
@@ -870,12 +872,12 @@ oj_num_as_value(NumInfo ni) {
870
872
  buf[ni->len] = '\0';
871
873
  rnum = rb_cstr_to_inum(buf, 10, 0);
872
874
  } else {
873
- char *buf = ALLOC_N(char, ni->len + 1);
875
+ char *buf = OJ_R_ALLOC_N(char, ni->len + 1);
874
876
 
875
877
  memcpy(buf, ni->str, ni->len);
876
878
  buf[ni->len] = '\0';
877
879
  rnum = rb_cstr_to_inum(buf, 10, 0);
878
- xfree(buf);
880
+ OJ_R_FREE(buf);
879
881
  }
880
882
  } else {
881
883
  if (ni->neg) {
@@ -1076,12 +1078,12 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
1076
1078
  size_t len = lseek(fd, 0, SEEK_END);
1077
1079
 
1078
1080
  lseek(fd, 0, SEEK_SET);
1079
- buf = ALLOC_N(char, len + 1);
1081
+ buf = OJ_R_ALLOC_N(char, len + 1);
1080
1082
  pi->json = buf;
1081
1083
  pi->end = buf + len;
1082
1084
  if (0 >= (cnt = read(fd, (char *)pi->json, len)) || cnt != (ssize_t)len) {
1083
1085
  if (0 != buf) {
1084
- xfree(buf);
1086
+ OJ_R_FREE(buf);
1085
1087
  }
1086
1088
  rb_raise(rb_eIOError, "failed to read from IO Object.");
1087
1089
  }
@@ -1163,9 +1165,9 @@ CLEANUP:
1163
1165
  oj_circ_array_free(pi->circ_array);
1164
1166
  }
1165
1167
  if (0 != buf) {
1166
- xfree(buf);
1168
+ OJ_R_FREE(buf);
1167
1169
  } else if (free_json) {
1168
- xfree(json);
1170
+ OJ_R_FREE(json);
1169
1171
  }
1170
1172
  stack_cleanup(&pi->stack);
1171
1173
  if (pi->str_rx.head != oj_default_options.str_rx.head) {