Coverage Report

Created: 2026-10-28 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
};