1 /***********************************************************************/
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. All rights reserved. This file is distributed */
9 /* under the terms of the GNU Library General Public License, with */
10 /* the special exception on linking described in file ../LICENSE. */
12 /***********************************************************************/
16 /* Operations on objects */
30 CAMLprim value
caml_static_alloc(value size
)
32 return (value
) caml_stat_alloc((asize_t
) Long_val(size
));
35 CAMLprim value
caml_static_free(value blk
)
37 caml_stat_free((void *) blk
);
41 /* signal to the interpreter machinery that a bytecode is no more
42 needed (before freeing it) - this might be useful for a JIT
45 CAMLprim value
caml_static_release_bytecode(value blk
, value size
)
48 caml_release_bytecode((code_t
) blk
, (asize_t
) Long_val(size
));
50 caml_failwith("Meta.static_release_bytecode impossible with native code");
56 CAMLprim value
caml_static_resize(value blk
, value new_size
)
58 return (value
) caml_stat_resize((char *) blk
, (asize_t
) Long_val(new_size
));
61 CAMLprim value
caml_obj_is_block(value arg
)
63 return Val_bool(Is_block(arg
));
66 CAMLprim value
caml_obj_tag(value arg
)
69 return Val_int (1000);
70 }else if (Is_young (arg
) || Is_in_heap (arg
) || Is_atom (arg
)){
71 return Val_int(Tag_val(arg
));
73 return Val_int (1001);
77 CAMLprim value
caml_obj_set_tag (value arg
, value new_tag
)
79 Tag_val (arg
) = Int_val (new_tag
);
83 CAMLprim value
caml_obj_block(value tag
, value size
)
91 if (sz
== 0) return Atom(tg
);
92 res
= caml_alloc(sz
, tg
);
93 for (i
= 0; i
< sz
; i
++)
94 Field(res
, i
) = Val_long(0);
99 CAMLprim value
caml_obj_dup(value arg
)
106 sz
= Wosize_val(arg
);
107 if (sz
== 0) CAMLreturn (arg
);
109 if (tg
>= No_scan_tag
) {
110 res
= caml_alloc(sz
, tg
);
111 memcpy(Bp_val(res
), Bp_val(arg
), sz
* sizeof(value
));
112 } else if (sz
<= Max_young_wosize
) {
113 res
= caml_alloc_small(sz
, tg
);
114 for (i
= 0; i
< sz
; i
++) Field(res
, i
) = Field(arg
, i
);
116 res
= caml_alloc_shr(sz
, tg
);
117 for (i
= 0; i
< sz
; i
++) caml_initialize(&Field(res
, i
), Field(arg
, i
));
122 /* Shorten the given block to the given size and return void.
123 Raise Invalid_argument if the given size is less than or equal
124 to 0 or greater than the current size.
127 Change the length field of the header. Make up a white object
128 with the leftover part of the object: this is needed in the major
129 heap and harmless in the minor heap.
131 CAMLprim value
caml_obj_truncate (value v
, value newsize
)
133 mlsize_t new_wosize
= Long_val (newsize
);
134 header_t hd
= Hd_val (v
);
135 tag_t tag
= Tag_hd (hd
);
136 color_t color
= Color_hd (hd
);
137 mlsize_t wosize
= Wosize_hd (hd
);
140 if (tag
== Double_array_tag
) new_wosize
*= Double_wosize
; /* PR#156 */
142 if (new_wosize
<= 0 || new_wosize
> wosize
){
143 caml_invalid_argument ("Obj.truncate");
145 if (new_wosize
== wosize
) return Val_unit
;
146 /* PR#61: since we're about to lose our references to the elements
147 beyond new_wosize in v, erase them explicitly so that the GC
148 can darken them as appropriate. */
149 if (tag
< No_scan_tag
) {
150 for (i
= new_wosize
; i
< wosize
; i
++){
151 caml_modify(&Field(v
, i
), Val_unit
);
153 Field (v
, i
) = Debug_free_truncate
;
157 /* We must use an odd tag for the header of the leftovers so it does not
158 look like a pointer because there may be some references to it in
160 Field (v
, new_wosize
) =
161 Make_header (Wosize_whsize (wosize
-new_wosize
), 1, Caml_white
);
162 Hd_val (v
) = Make_header (new_wosize
, tag
, color
);
167 /* The following functions are used in stdlib/lazy.ml.
168 They are not written in O'Caml because they must be atomic with respect
172 CAMLprim value
caml_lazy_follow_forward (value v
)
174 if (Is_block (v
) && (Is_young (v
) || Is_in_heap (v
))
175 && Tag_val (v
) == Forward_tag
){
176 return Forward_val (v
);
182 CAMLprim value
caml_lazy_make_forward (value v
)
187 res
= caml_alloc_small (1, Forward_tag
);
188 Modify (&Field (res
, 0), v
);
192 /* For camlinternalOO.ml
193 See also GETPUBMET in interp.c
196 CAMLprim value
caml_get_public_method (value obj
, value tag
)
198 value meths
= Field (obj
, 0);
199 int li
= 3, hi
= Field(meths
,0), mi
;
201 mi
= ((li
+hi
) >> 1) | 1;
202 if (tag
< Field(meths
,mi
)) hi
= mi
-2;
205 return Field (meths
, li
-1);
208 /* these two functions might be useful to an hypothetical JIT */
216 value
caml_cache_public_method (value meths
, value tag
, value
*cache
)
218 int li
= 3, hi
= Field(meths
,0), mi
;
220 mi
= ((li
+hi
) >> 1) | 1;
221 if (tag
< Field(meths
,mi
)) hi
= mi
-2;
224 *cache
= (li
-3)*sizeof(value
) + MARK
;
225 return Field (meths
, li
-1);
228 value
caml_cache_public_method2 (value
*meths
, value tag
, value
*cache
)
230 value ofs
= *cache
& meths
[1];
231 if (*(value
*)(((char*)(meths
+3)) + ofs
- MARK
) == tag
)
232 return *(value
*)(((char*)(meths
+2)) + ofs
- MARK
);
234 int li
= 3, hi
= meths
[0], mi
;
236 mi
= ((li
+hi
) >> 1) | 1;
237 if (tag
< meths
[mi
]) hi
= mi
-2;
240 *cache
= (li
-3)*sizeof(value
) + MARK
;