/src/ghostpdl/psi/zvmem2.c
Line | Count | Source |
1 | | /* Copyright (C) 2001-2026 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Level 2 "Virtual memory" operators */ |
18 | | #include "ghost.h" |
19 | | #include "oper.h" |
20 | | #include "estack.h" |
21 | | #include "dstack.h" |
22 | | #include "iddict.h" |
23 | | #include "ialloc.h" /* for ivmspace.h */ |
24 | | #include "ivmspace.h" |
25 | | #include "ivmem2.h" |
26 | | #include "store.h" |
27 | | |
28 | | /* Garbage collector control parameters. */ |
29 | 0 | #define DEFAULT_VM_THRESHOLD_SMALL 100000 |
30 | 162k | #define DEFAULT_VM_THRESHOLD_LARGE 8000000 |
31 | | |
32 | | /* ------ Local/global VM control ------ */ |
33 | | |
34 | | /* <bool> .setglobal - */ |
35 | | static int |
36 | | zsetglobal(i_ctx_t *i_ctx_p) |
37 | 496M | { |
38 | 496M | os_ptr op = osp; |
39 | 496M | int code; |
40 | 496M | uint space = r_space(systemdict); |
41 | | |
42 | 496M | check_op(1); |
43 | 496M | check_type(*op, t_boolean); |
44 | 496M | ialloc_set_space(idmemory, (op->value.boolval ? avm_global : avm_local)); |
45 | | |
46 | | /* We have to rebind the name /FontDirectory to suit the mode */ |
47 | | /* Hack the VM mode so we can write the local LocalFontDirectory |
48 | | to the global systemdict |
49 | | */ |
50 | 496M | r_set_space(systemdict, avm_local); |
51 | 496M | if (op->value.boolval) |
52 | 478M | code = idict_put_string(systemdict, "FontDirectory", &i_ctx_p->GlobalFontDirectory); |
53 | 18.0M | else |
54 | 18.0M | code = idict_put_string(systemdict, "FontDirectory", &i_ctx_p->LocalFontDirectory); |
55 | 496M | r_set_space(systemdict, space); |
56 | | |
57 | 496M | if (code < 0) |
58 | 0 | return code; |
59 | | |
60 | 496M | pop(1); |
61 | 496M | return 0; |
62 | 496M | } |
63 | | |
64 | | /* - .currentglobal <bool> */ |
65 | | static int |
66 | | zcurrentglobal(i_ctx_t *i_ctx_p) |
67 | 278M | { |
68 | 278M | os_ptr op = osp; |
69 | | |
70 | 278M | push(1); |
71 | 278M | make_bool(op, ialloc_space(idmemory) != avm_local); |
72 | 278M | return 0; |
73 | 278M | } |
74 | | |
75 | | /* <any> gcheck/scheck <bool> */ |
76 | | static int |
77 | | zgcheck(i_ctx_t *i_ctx_p) |
78 | 118M | { |
79 | 118M | os_ptr op = osp; |
80 | | |
81 | 118M | check_op(1); |
82 | 118M | make_bool(op, (r_is_local(op) ? false : true)); |
83 | 118M | return 0; |
84 | 118M | } |
85 | | |
86 | | /* ------ Garbage collector control ------ */ |
87 | | |
88 | | /* These routines are exported for setuserparams. */ |
89 | | |
90 | | /* |
91 | | * <int> setvmthreshold - |
92 | | * |
93 | | * This is implemented as a PostScript procedure that calls setuserparams. |
94 | | */ |
95 | | int |
96 | | set_vm_threshold(i_ctx_t *i_ctx_p, int64_t val) |
97 | 850k | { |
98 | 850k | if (val < -1) |
99 | 0 | return_error(gs_error_rangecheck); |
100 | 850k | else if (val == -1) |
101 | 162k | val = (gs_debug_c('.') ? DEFAULT_VM_THRESHOLD_SMALL : |
102 | 162k | DEFAULT_VM_THRESHOLD_LARGE); |
103 | | #if PSINT32BIT==1 |
104 | | else if (val > max_int) |
105 | | val = max_int |
106 | | #endif |
107 | 850k | gs_memory_set_vm_threshold(idmemory->space_system, val); |
108 | 850k | gs_memory_set_vm_threshold(idmemory->space_global, val); |
109 | 850k | gs_memory_set_vm_threshold(idmemory->space_local, val); |
110 | 850k | return 0; |
111 | 850k | } |
112 | | |
113 | | int |
114 | | set_vm_reclaim(i_ctx_t *i_ctx_p, long val) |
115 | 849k | { |
116 | 849k | if (val >= -2 && val <= 0) { |
117 | 849k | gs_memory_set_vm_reclaim(idmemory->space_system, (val >= -1)); |
118 | 849k | gs_memory_set_vm_reclaim(idmemory->space_global, (val >= -1)); |
119 | 849k | gs_memory_set_vm_reclaim(idmemory->space_local, (val == 0)); |
120 | 849k | return 0; |
121 | 849k | } else |
122 | 0 | return_error(gs_error_rangecheck); |
123 | 849k | } |
124 | | |
125 | | /* |
126 | | * <int> .vmreclaim - |
127 | | * |
128 | | * This implements only immediate garbage collection: enabling and |
129 | | * disabling GC is implemented by calling setuserparams. |
130 | | */ |
131 | | static int |
132 | | zvmreclaim(i_ctx_t *i_ctx_p) |
133 | 161k | { |
134 | 161k | os_ptr op = osp; |
135 | | |
136 | 161k | check_op(1); |
137 | 161k | check_type(*op, t_integer); |
138 | 161k | if (op->value.intval == 1 || op->value.intval == 2) { |
139 | | /* Force the interpreter to store its state and exit. */ |
140 | | /* The interpreter's caller will do the actual GC. */ |
141 | 161k | return_error(gs_error_VMreclaim); |
142 | 161k | } |
143 | 0 | return_error(gs_error_rangecheck); |
144 | 161k | } |
145 | | |
146 | | /* ------ Initialization procedure ------ */ |
147 | | |
148 | | /* The VM operators are defined even if the initial language level is 1, */ |
149 | | /* because we need them during initialization. */ |
150 | | const op_def zvmem2_op_defs[] = |
151 | | { |
152 | | {"0.currentglobal", zcurrentglobal}, |
153 | | {"1.gcheck", zgcheck}, |
154 | | {"1.setglobal", zsetglobal}, |
155 | | /* The rest of the operators are defined only in Level 2. */ |
156 | | op_def_begin_level2(), |
157 | | {"1.vmreclaim", zvmreclaim}, |
158 | | op_def_end(0) |
159 | | }; |